1月メモ編集用

# 正月やったことの質問# 正月やったことの質問
```cnm017:environment $ lshello_app lacotto_app ruby-book sample_app toy_appcnm017:environment $ cd ruby-book-bash: cd: ruby-book: Not a directorycnm017:environment $ cd hello_app/自分で作った[ruby-book]
ruby-bookはファイルであり、ディレクトリではないから```
```Cookieに保存するものが登録不要なので、クライアントのブラウザのIDのようなものを保存する必要がある。```
```cookieを保存するときの書き方は、alertを使うのか?それとも保存するようなオプション、メソッドなどがあるのか?```
## わからないこと整理* HTMLの属性が[rails.erb]の記述でどのように生成されるのかを理解していないので、`style属性`などを使うとわかった場合でもどのように、`style属性`[erb]に記述すればいいのか理解していない。
## 質問内容* atomの[All replace]機能ですべてのインデントを左にずらす、スペース削除をしてしまった。→git等を使って一気に前の段階のコードに戻る方法。もしくはatom自体で一つ前の動作(ファイル全件の一つ前の動作)に戻る方法などはあるのか?→atomで一つ前の`command + Z`では戻ることのできないファイルもあった。* `token`とは?

 

# 1月9日
cookieに追加
```
document.cookie = "(cookieのname)=" + "(cookievalue)"
```

coffeescriptを使うときには([CoffeeScript](https://coffeescript.org/))で試してみながらjavascriptでどのように反映されるか確認しながらする。

```
cookieのパス指定について
coffeescript内↓
document.cookie = "keeps=" + new_keeps + ";" + "path=/"
document.cookie = "tanaka=tarou;path=/"


```


今、`keepした求人から一括応募する` 処理を実装しているところで悩んでいて、
一括で `save` しようとすると最後のレコードが `update` でデータを上書きしてしまい、結局最後のレコード一つしか応募ができてません。


コードは下記のように書いています。

<app/controllers/entries_controller.rb>
```
(省略)
def keeps_create
get_keeps_ids
@entry = Entry.new(keeps_entry_params) ←←問題のコード
@keep_ids_arr.each do |job_offer_id|
@entry[:job_offer_id] = job_offer_id
if @entry.save
next
else
render("keeps_new")
break
end
end
end

@entry = Entry.new(keeps_entry_params)をeach文の中に入れずにしてるので、フープ内での変更もできず、プライマリーキーが重複してしまい。あっぷでーとしてしまう;
```


### Q:「キープする」→「キープ済み」を瞬時に表示を変えたい。
検索「javascript display none 切り替え」=>[表示・非表示-JavaScript入門](https://www.pazru.net/js/DOM/7.html)
これを見て解決。
```
<views側>
id="disp1" , id="disp2" としてして、「表示/非表示」で切り替えるようにした。

document.getElementById("disp1").style.display="block"
document.getElementById("disp2").style.display="none”

上記のサイトの説明で<div id="設定名"></div>のようにしているが、今回瞬時に表示を変えたいのは<aタグ>なので、<a id="設定名"></a>のように設定をしないといけません。
```

# 自分コード_処女作
```
# # keeps追加するとき
# @keep = (keep_id) ->
# cookies_arr = document.cookie.split(';')
# new_keeps_value = keep_id
# for cookie_element in cookies_arr
# cookie_arr = cookie_element.split('=')
# if (cookie_arr[0].trim() == "keeps")
# old_keeps = cookie_arr[1].split('&')
# old_keeps.push(keep_id)
# keeps_value = Array.from(new Set(old_keeps))
# new_keeps_value = keeps_value.join('&')
# break
# document.cookie = "keeps=" + new_keeps_value + ";" + "path=/"
# document.cookie = "furufuru=hirohiro;" + "path=/"
#
# # keeps削除するとき
# @not_keep = (keeped_id) ->
# cookies_arr = document.cookie.split(';')
# for cookie_element in cookies_arr
# cookie_arr = cookie_element.split('=')
# if (cookie_arr[0].trim() == "keeps")
# old_keeps = cookie_arr[1].replace(keeped_id, "")
# old_keeps_arr = old_keeps.split('&')
# keeps_value =
# for cookie_element in old_keeps_arr
# if (cookie_element != "")
# keeps_value.push(cookie_element)
# new_keeps_value = keeps_value.join('&')
# break
# document.cookie = "keeps=" + new_keeps_value + ";" + "path=/"
# document.cookie = "furufuru=hirohiro;" + "path=/"

```

## 意識すること
戻り値が何が返ってくるのか。
戻り値だから出力されている。出力されているから戻り値なのではない。
メソッドの引数に渡す値を意識する。

 

```
<rubyでidの削除をやってみる。>
a = "1&2&3&4"
a.slice!('1')
=> "&2&3&4"
b = a.split('&')
=> ["", "2", "3", "4"]
c = b.compact.delete_if(&:empty?)
=> ["2", "3", "4"]
d = c.join('&')
=> "2&3&4"
```

 

## わからないこと
- coffeescriptの書き方を理解してない。
- javascriptの書き方を忘れているから。
- cookiesハッシュの値を出力することができない。

 

`function...様々な処理を1つにまとめて、名前をつけることができるもの`

 

### 1月18日
```
# keeps追加するとき
@keep = (keep_id) ->
##①cookieの配列を取り出す
cookies_arr = document.cookie.split(';')
new_keeps_value = keep_id
for cookie_element in cookies_arr
cookie_arr = cookie_element.split('=')
if (cookie_arr[0].trim() == "keeps")
old_keeps = cookie_arr[1].split('&')
## ②配列にキープを追加する
old_keeps.push(keep_id)
keeps_value = Array.from(new Set(old_keeps))
new_keeps_value = keeps_value.join('&')
## ③キープを文字列に戻す
document.cookie = "keeps=" + new_keeps_value + ";" + "path=/"
document.cookie = "tanaka=tarou;" + "path=/"

```
↓↓↓
3工程に分けて、関数を①〜③で分けて定義する。
↓↓↓
読みやすさと今後の処理の手間を省くため
↓↓↓
```
>>>>>>①cookieの配列を取り出す
cookie_pick_up = ->
cookies_arr = document.cookie.split(';')
old_keeps =
for cookie_element in cookies_arr
cookie_arr = cookie_element.split('=')
if (cookie_arr[0].trim() == "keeps")
old_keeps = cookie_arr[1].split('&')

>>>>>>③キープを文字列に戻す
cookie_put_in = (job_offer_ids)->
document.cookie = "keeps=" + job_offer_ids + ";" + "path=/"
document.cookie = "tanaka=tarou;" + "path=/"

>>>>>>②keeps追加するとき<<<<<①、③の関数も入れる
@keep = (keep_id) ->
old_keeps = cookie_pick_up() ←①関数呼び出し
→ ①cookie_pick_up()関数の戻り値を代入している
 ## ②配列にキープを追加する
old_keeps.push(keep_id)
keeps_value = Array.from(new Set(old_keeps))
new_keeps_value = keeps_value.join('&')
cookie_put_in(new_keeps_value) ←③関数呼び出し
→③関数の引数に(new_keeps_value)を代入して呼び出す

```

Coffeescript で生成されたjavascript が意図した戻り値を返していなかった。
```
生成されたjsが
`return result;`
になっていて、本当は`old_keeps`という値を戻り値として返したい。

* 「return result  javascript」で検索して、resultは変数で、関数の戻り値として設定したい場合は、`return 変数名`みたいな形で設定しないといけない。ということが分かる。
↓↓↓↓↓↓↓↓
* 「coffeescript 戻り値」で検索して、どのように戻り値を変数ニセってすればよいか、その方法を調べて解決した。
```

# 1月16日

<ビューヘルパーについて、使い方で躓いた>
```
<知ったこと>
* 引数の順番で入れる要素の値が決まっている。
* [,######]のように書かれているのは"省略可"というもの。
* 勝手に()などで囲ったりするだけで、エラーになってしまうこともある。

●セレクトボックス
f.select(プロパティ名, タグの情報 [, オプション])
第一引数:プロパティ名
第二引数:タグの情報
第三引数:オプション(省略可)

●チェックボックス
f.check_box(プロパティ名 [, オプション, checked_value = "1", unchecked_value = "0"])
第一引数:プロパティ名
第二引数:オプション(省略可)
第三引数:value(省略可)

<例>
<%= f.check_box 'freezeflag', {:disabled => true}, true, false %>
オプション→ {:disabled => true}
チェックした時の値→ true
チェックが空の時の値→ false

checked_value = "1" のように書かずに、値だけの「true」だけで書く。このように使い方の例を確認してから、どのようにしているか理解する。

```

keepsへの追加と削除は関数をわけたほうがよいと思います。
coffeescript内で関数はいくつでも定義することができて、名前もなんでも定義できる(スクリプトタグでjsに変更できない場合に関してはその関数は定義することができない。)

 

# 1月21日

### Name属性について
<formタグ内>だと、、、
`<input value="2 3 4" type="hidden" name="entry[job_offer_id]" />`
`名前(全角):<input placeholder="山田" type="text" name="entry[first_name]" />`

Rails側に送るハッシュの`キー`の様な役割をしている。
=>name属性が分からなければdevツールで何が表示されているのか。それがリクエスト先でどの様なものになっているのか。
=>HTML、ネットで分からないコードがある場合には、viewにコードをコピペして、どのように表示するのか見てみる。

 

### ストロングパラメータで`entry=>{}`のハッシュの中に入れれない
<before>
```
<input type="hidden" name="job_offer_ids" value="<%= job_offer.id %>">

=>
"job_offer_ids" => [1, 2], "entry" => ...
```

<after>
```
<input type="hidden" name="entry[job_offer_ids]" value="<%= job_offer.id %>">

<間違った考え方>
@entryに`job_offer_ids`を入れる方法が、
[f.hidden_field]の様な[f]を使うやり方だと決め込んで調べていたので、迷っていた。
<こう考えるべきであった>
今回はbeforeのコードと出力の結果を見て、name属性でパラメータの値が変わるのならそこをいじればいいんじゃないかと考えるべきであった。視野をもっと広げる必要がある。

name属性をentryで囲む事によってできるようになった。
=>
"entry"=> < {"job_offer_ids"=>["1", "2"], ... >

```

### トランザクション save! の処理
* Entryモデル(応募) と JobOfferモデル(求人)を`has_many_through`
された EntryJobOfferモデル(応募求人)があり、求人を選択して応募したが、選択した求人が存在しなかった場合のトランザクション処理。

```
@entry.save!
このsave!で下記のトランザクションの処理をできたことにしている。
この@entryには
@entry.job_offer_ids = [1, 2]の様にjob_offerとの関連付けもsave前にされている状態。この状態だと、良しなにsave!だけで、下記の様な<rails側>のトランザクション処理を実装しなくともしてくれる。<SQL側>の処理の流れで「job_offers(3)」が求人掲載を終了しており、insertしていなかったときは,save!だけでトランザクション処理でなかったことにする。
--------<rails側でいうと>-------
Entry.transaction do
@entry_job_offer_ids = Array.new
params[:job_offer_id].each do |job_offer_id|
@entry = Entry.new(entry_params)
@entry.job_offer_id = job_offer_id
@entry_job_offer_ids << @entry.job_offer_id if @entry.save
@entry = Entry.new(entry_params)
@entry.job_offers << JobOffer.find(params[:job_offer_id])
@entry.save
end
-------------------------------


--------<SQL側でいうと>-------
insert entries...
...
insert job_offers(1)...
...
insert job_offers(2)...
...
insert job_offers(3)...××(トランザクションで中断する)
-------------------------------

```

### create!メソッド
create は save の成功可否にかかわらず、一応結果オブジェクトを返してしまうので、
`if @entry.create!`みたいなものだと必ずその処理を通ってしまい。 失敗している場合、MyModel にレコードは作成されていない。

[ActiveRecord::Baseのcreateとsaveの違い - woshidan’s blog](https://woshidan.hatenablog.com/entry/2015/09/29/224750)

 

### 課題

- テスト実行時に自動的にfixtureを読み込むようにする。
RSpecコマンドで`rails db:fixtures:load`でテスト実行時自動的に読み込むようにした。
→下記の2つのファイルに自動でフィクスチャを呼び出すための項目を追加する内容を調べたがよくわからない。。。
→`rails_helper.rb`と`spec_helper.rb`で設定するはずで、このファイルがどの様な時に呼び出されて、どの様な役割をしているか。railsガイド見てみる。
RSpecのホークスとは!

- spec/models/entries_spec.rbのbeforeアクションの存在意義を考える。あと、呼び出し順も考える。

- spec/rails_helper.rbのbeforeアクションのところにseeds.rbを消す処理を入れる→「どうやって調べるの?」、「」

- エラーメッセージまでテストする様にする。

+ もらったレビュー
```
expect(xxx.empty?).to be true
expect(xxx).to be_empty   ←こうした方が見やすい。

https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers

check_the_municipality_associated_with_prefecture メソッドのテスト内容はあまりよくない。

``
Entryモデル内のカスタムメソッドに関わるところに対してテストを作成しました。
* `birth_date`
* `check_the_municipality_associated_with_prefecture`メソッド
``

そもそもレベルがそろっていない。

+ メソッドをテストするなら `prefecture_id` , `municipality_id` が属する関係として正しいか正しくないかだけの検証をします。(東京都目黒区:○、 北海道目黒区:×)

+ 6年半のコードの箇所直します。
→travel_to を使わずにできた。
```
- testでエラーメッセージまでをチェックするようにする。

- ymlファイルでフォーマットエラーが出ているので、そこの書き方を調べる
- 他のファイルも見てみる

———————————————————————————————————————————————

POST したい場合は、ユーザインターフェースの操作をシミュレートして click するか、 RackTest のインターフェースを使って POST させるか、素直に RackTest の API を使う。

`capybara-webkit`や`Selenium`はブラウザエンジンである。
テスト内容を考慮してこのブラウザエンジンを切り替えてテストする。

```
expect do
post :create, params: {entry: attributes_for(:entry)}
end.to change(Article, :count).by(1)
```

コントローラーテストをするということ?

 

### できるようになったこと
<vimでコミットメッセージを修正する>
```

$ git commit --amend

iコマンド...INSERTモードに変える。
escコマンド...INSERTモードからNormalモードに戻る。
:wコマンド...書き込む
:q...閉じる


```

### RSpecを書く時
```
テスト用のテーブルのマスターテーブルを作成していないくて、エラーが出ていた。

$ bundle exec rails db:migrate RAILS_ENV=test

RAILS_ENVで指定してテーブルを作成する。

```


### <rails_helper.rb>にrails関係の設定を書く。

### travel_toで時間を設定して、テストするようにする。
[ActiveSupport::Testing::TimeHelpers](https://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel_to)
```
→メリットとしては日付が変わった時のエラーを防ぐため。

●影響範囲に注意する(ブロックだとそのスコープ内だけになる。)
`ブロックの場合` と `単体の場合`

```

### railsのコマンドの確認
```
$ bundle exec rails -T
標準的に利用できるコマンドがでてくる。
```

### transaction と truncation について(テスト実行時にデータを全部削除してから、seeds.rbを読み込みしたかった。)
[GitHub - DatabaseCleaner/database_cleaner: Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing.](https://github.com/DatabaseCleaner/database_cleaner#rspec-example)
```
テスト実行時にデータを全部削除してから、seeds.rbを読み込みしたかった。
DatabaseCleanerを使った。

truncation については、DBのデータを全部削除する。(テーブルは残したまま)なので、下記のように今回はseedを読み込む前にtruncationを持ってくる。

RSpec.configure do |config|
(省略...)
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation) ←ココ
load Rails.root.join('db', 'seeds.rb')
end
(省略...)
end
```
また、[ RSpec ] ではなく [ Minitest ] だが下記のようにtransactionをかく。
https://github.com/DatabaseCleaner/database_cleaner#minitest-example

※また、githubでRead.Meを見る時に「RSpec Example」,「Minitest Example」のように書いてあるので、使用例を調べたりする。

 

 

```
let(:job_offer) {FactoryBot.create(:job_offer)}
→上記だと、定義した後に[job_offer]で呼び出さないと[job_offer]ができたことにはならない。

let!(:job_offer) {FactoryBot.create(:job_offer)}
→上記のように[!]をつけることで、[job_offer]に設定
```

### hidden_field_tagを使って、パラメータを渡す。
```

※<%= hidden_field_tag "entry[birth_date(1i)]", @entry.birth_date.year %>
=>
<input type="hidden" id="entry_birth_date_1i" name="entry[birth_date(1i)]" value="1945">

[f.hidden_field]を使う理由としては、form_withタグの@modelの中身の要素を使う時に使用する。

今回、"entry[birth_date(1i)]"を使いたいので、@modelにある要素ではない。よって、f.hidden_fieldは使えない。(つまり、hidden_field_tagを使う。)

<今回の反省点>
・f.hidden_fieldをどうしても使わないといけないと思っていた。
・上記とhidden_field_tagの違いを理解していなかった。
・name属性を指定すれば、params[:entry]で送ることができる。ということに気づけなかった。(f.hidden_fieldでどうにかして、そのまま綺麗に渡せないか考えていた。)


```

 

## ・新たに理解したこと
環境変数
export:環境変数の定義
printenv:確認、外部コマンド
echo:確認、シェル変数にも
unset:削除
PATH:実行する時の道のり
cat:ファイル閲覧($ cat ~/.bash_profile )

・rbenvの理解(体系的にイラストで理解)
`$ rbenv versions`で管理下のrubyのバージョンが確認できる。
` $ rbenv -v`でrbenv自身のバージョンの確認
PCに元々入っているruby-versionは`system`で表示されている
`$ rbenv global XXX`システム全体のruby-versionを指定する
`$ rbenv local XXX`プロジェクト毎に使うruby-versionを指定する

Linuxコマンド(gitコマンドも)
`$ ps aux`PCが熱くなったときアクティビティを確認する。

 


## ・よくわからないこと
*・環境変数*
`$ echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile`
...PATHを追加するとき、上記のように環境変数を確認する為の`echoコマンド`を入れる理由がわからない。
`echo 変数`のように変数を表示するコマンド。

*・Linuxコマンド(gitコマンドも)*
`$ git push -u origin —all`の意味。
特に[-u]コマンドが何のためなのか分からない。
[-u]...「 最後にファイルにアクセスした時刻でソート。詳細表示時には時刻欄が最後にファイルにアクセスした時間になる 」らしい。。
[—all]… 「すべてのファイルを表示する」

*・railsチュートリアル*
`inspectメソッド`…「オブジェクトを分かりやすい文字列にして返す」
(下記の様に)前置した物をそのまま出力するということなのか?
```
>> puts (1..5).to_a # 配列を文字列として出力
1
2
3
4
5
>> puts (1..5).to_a.inspect # 配列のリテラルを出力
[1, 2, 3, 4, 5]
>> puts :name, :name.inspect
name
:name
>> puts "It worked!", "It worked!".inspect
It worked!
"It worked!"
```


*・testについて*
testの書き方、コードの理解・読むことが出来ない
(特にアサーション理解していない)
https://railsguides.jp/testing.html#2.6 利用可能なアサーション


test/integration/site_layout_test.rbでの
①root_pathなどのところ
②count: 2のところ
`$ assert_select “a**[**href=?**]**”**,**root_path**,**count: 2`
といった風に書くことで、 [リスト 5.30](https://railstutorial.jp/chapters/filling_in_the_layout?version=5.1#code-header_partial_links) で定義したHomeページのリンクの個数も調べることもできます


*・helperについて*
Helperの書き方が分からない、コードの理解読む事はできる
(「Viewをシンプルにする為のモジュールって感じ」のニュアンスでいるが、どのように連携?しているのか。理解できていない)