# 【第2週】パRails輪読会 \(2022\-08\-01\~ 2022\-08\-05\)
###### tags: `パRails(2回目)`
- [開催概要](https://hackmd.io/rOcLR0riRqmOgEF0_Ssm0A?both)
- [パRails輪読会 ノートまとめ](https://hackmd.io/5emISRvRRXapmakSiHnFJg?both)
## パRailsのサンプルコード・正誤表
- [サポートページ:パーフェクトRuby on Rails【増補改訂版】:|技術評論社](https://gihyo.jp/book/2020/978-4-297-11462-6/support)
## 目次
[TOC]
------
## 2022\-08\-01(月)
### 連絡事項や確認・相談
### タイムキーパー
### ドライバー
### 読んだところ
P.46 [1-4-5 scaffoldで生成されたコントローラとルーティング]~
### 次回
P.54 [2-2-1 DBに登録されているレコードを1件だけ検索する]〜
### 先輩が教えてくださったこと
### 自由に使う共有スペース
`bundle update`をして`check_yarn_integrity: false`
### 各自の疑問点や気づき、学んだこと
- @napple29
- アプリが出来上がっている弊害で簡単にデータ作れないのわらいました
- rails始めた頃、確かに `def edit; end` とか何も書いてないのにいらなくない?と思ってました
- @maimux2x
- before_actionの部分は自分の中にパッと説明が出てこなかったのでなるほどとなった。
- @saki
- `show`や`edit`の中身がまっさらでもちゃんと動く理由忘れかけていたので、勉強になった!`before_action`で`set_task`が設定されているから。
- たしかに同じインスタンス変数を複数のアクションで書くとどんどんFatになっていって読みづらくなるなと思った
- railsちょっと離れてると、リクエスト→レスポンスまでの流れを忘れがちなので良い復習になった
- すでにあぷりできあがってる弊害😭
- @paru871
- 図1-9のルーティングからテンプレート描画までの流れが勉強になった
- モデルの持つ役割が確認できた、データベースとの接続とデータに対する操作、及びビジネスロジック
* @mh0ri(仕事中のため代読お願いしますw)
* rails cはとてもよく使います...(今日も仕事で10回以上は使った。jsでいうところのconsole.logみたいなもの)
- @garammasala29
- rails cを使ったカラム情報取得はあまりやたことがなかったけど便利
- `create!`を使った検証もとても便利
- ActiveRecordの特徴、文章でみるとなるほどなぁと思う
- SQLの構築を抽象化
- コネクションプール(一度作った接続窓口を使い回す)
- 接続情報の隠蔽
- @fugakkbn
- rails c --sandbox でコンソール起動すると、変更してもロールバックしてくれるので安全にデータを扱えるので思い切りいじくり倒せます。
- ActiveRecord の CRUD 系 API は、ほとんど `!` 付きを使っている。他のプロジェクトはどうなのか気になる
### 本日の振り返り(よかった点・次回に向けての改善点等)
- @maimux2x
- データの話などはDB設計のプラクティスとも関連があるため、復習ちゃんとしようと思いまいました。
- @saki
- モブプロの進め方どうしましょうかね...1からみんなで作っていく方が勉強になる&分かりやすいけれど、ドライバーは毎日変わるので、そこが手間ですね...ご意見書いてくださるとうれしいです👇
- @fugakkbn リポジトリ作ってPR方式にするのも勉強になっていいかもですね。
- @paru871 そうですねー。Gitに慣れるのも早めに取り組んで置いたほうが後々楽になるかもしれないですね。
- @napple29 めっちゃ自分のとこに書きました🤔
- @napple29
- 個人的には1から作る形式ならgit管理とかになるんですかね
- 最初の2週間くらい環境構築系で何かしらつまづきそうですがそれも勉強になりそう?
- 読みたい部分のどこに重きを置くかも大事かなと思いました。x
- 色々書きましたがLT会お疲れ様でした!!maimuさんもyamabeさんも発表がわかりやすくて、どうしたらそんなにわかりやすくスライド作れるのか知りたいです😂
- @fugakkbn
- なんでうまく動かないの?というものの理由がわかると気持ちいいですよね
- 何回か前の私のつぶやきにいろいろご意見いただいてありがとうございました!
- ↑は「マイグレーションファイルの差分があるときのブランチ移動」の件でした〜
- はるなさん参考リンクありがとうございました🙏
- 他にもブログなど貼っていただいた方ありがとうございました!
- @paru871
- みんなでワイワイ試行錯誤していく感じがとっても楽しいですね!
- 先週末のLT会、ガラムマサラさん、ご参加の皆さん本当にお疲れさまでした!すごく楽しかったし、学びも多くて深くて最高でしたー!
- 今日はBuzzcordの表示のバグが出てて見づらくて申し訳ありませんでした🙏駒形さんのお力で速攻デプロイしていただけて今はもう直っています!
- order大切👮🏻♀️
- バッテリーが膨張して爆発すると脅かされたiPodtouchの修理が終わって新品交換になって返ってきましたー。
- iPodtouch!なんだか懐かしく感じました〜
* mh0ri(代読お願いしますww)
* createするときは1つずつやっても良かったかもしれない。必ず5つ作らなくてはいけないわけではないので。
* みんなで問題を解決しに行こうとする感じがとても良かった!!(喋れずすみません)
* 👏👏
- @garammasala29
- 土曜日のLT会のご参加ありがとうございました〜若干燃え尽き気味です
- :curry: :tea:
-----
## 2022\-08\-02(火)
### 連絡事項や確認・相談
### タイムキーパー
- @fuwa
### ドライバー
### 読んだところ
P.54 [2-2-1 DBに登録されているレコードを1件だけ検索する]〜
### 次回
P.63 [2-2-2 多対多のリレーションを実現する]~
### 先輩が教えてくださったこと
### 自由に使う共有スペース
### 各自の疑問点や気づき、学んだこと
- @fugakkbn
- scope とクラスメソッドの違いを改めて知れてよかった。忘れてしまっていた。
- デフォルトスコープは過激発言をしてしまったけど「用法容量を守って使いましょう」という話だと思うので、絶対悪ではないです🙏
- :naruhodo:
- @fuwa
- デフォルトスコープは気をつけて使わないといけないなーと思いました。
- 検索結果がnilの場合、クラスメソッドで定義したときはnilが返るのに対して、scopeで定義したときは該当scopeの検索条件を除外したクエリを発行してActiveRecord::Relationを返すというのは気をつけなければいけない気がする
- @hyumanase (すみません、用事ができてラジオに戻りますので、代読おねがいします🙏)
- 今日は"デフォルトスコープは用法容量を守って使いましょう!"を覚えて帰ります💪
- 著者の方々の人となりも知っていけばより本書楽しめそう〜
- @haruguchi
- `ActiveRecord::Relation`のおかげですぐにSQLを発行するのではなく、どんどんメソッドチェインしていって欲しい時にSQLを発行し、データを取得できるようになる
- アソシエーションはこれ読んだ時DB設計との関連性がつながって感動した覚えがある
- 便利メソッド勝手に生えるのすごい
- @saki
- 🤔疑問:`Book.where("price > ?", 3000)`は、`Book.where("price > 3000")`と書いても良さそうと思った。`?`はプレースホルダーというらしい
- そういえばsinatraでDBverをやった時に習った気がする!
- [【Rails】 whereメソッドを使って欲しいデータの取得をしよう! \| Pikawaka](https://pikawaka.com/rails/where)より
> SQLインジェクションを防ぐ書き方の一つ
- [Rails セキュリティガイド \- Railsガイド](https://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)
- `default_scope`は、たとえば`Book.order~`と書く場合、`Book`の時点で`default_scope`が発動してしまっている。ので、並び替えだけならまだしも検索して抽出するのがデフォルトスコープでついてしまってると、「あのレコードがあるはずなのに無い」となるので辛い。→個人開発ではDRYになってよさそうだけどチーム開発や大規模なサービスだと辛そう
### 本日の振り返り(よかった点・次回に向けての改善点等)
- @fugakkbn join, include, eager_load などはまだいまいち違いや使い所を把握できていないので、その辺りは今度深掘りしていきたい。
- @fuwa
- 次回の多対多のリレーションはごちゃごちゃしていたような記憶が。。
- 今日のお夕飯は餃子と肉です :urayama:
- @haruguchi
- Railsの大海原が垣間見える章ですね!:innocent:
- @saki
- モデルの関連付け、テーブルが増えると混乱しますね😇
- ちょうど自作サービスでmodel作ろうとしてたのでタイムリーでした!
-----
## 2022\-08\-03(水)
### 連絡事項や確認・相談
### タイムキーパー
### ドライバー
### 読んだところ
P.63 [2-2-2 多対多のリレーションを実現する]~
### 次回
p.69[2-2-4 コールバックによる制御]~
### 先輩が教えてくださったこと
### 自由に使う共有スペース
### 各自の疑問点や気づき、学んだこと
- @maimu_x2x
- バリデーションはDBでかけるのとRailsでかけるのとどう使い分けるのでしょうか?DB設計の本にはDB側でやったほうがいいようなことが書いてあった気がします。
- @fugakkbn 使い分けるというよりも、かけられるなら両方かける、が多い気がします。 :metoo:
- @napple29
- 毎回バリデーションかけたい時Railsガイドを見ています
- @fugakkbn :wakaru:
- :eyes:
- ブロック内に独自のバリデーションを書ける、エラーメッセージも書ける
- でも独自バリデーションがたくさんあるときはブロックで書くともっさりしそう
- @fugakkbn
- 使ったことないバリデーションがいっぱいあった!いつか使いたい
- @Saki
- 🤔p.64で中間テーブルの関連付けをモデルに書く時に、`models/book_authors`には何も書いてなかったが、こちらにも関連付けを書かないといけないのでは?と思った。この後出てくるのかな?
- 関連付けのコードだけ見てもしっくりこないけれど、`rails db`の`.mode line`で実際に中間テーブルのSQL文を発行してみると分かりやすかった
- バリデーション、Railsプラクティスの課題提出で、DBに`not_null`制約が付いてるからmodelに`validates`いらないと思って提出して、両方付けるべきとレビューいただいたのを思い出した
- ActiveRecordでsave時などエラーが出た時`errors`メソッドで、エラーの内容を知れる。が、`save!`など`!`をつければ出てくれるので、常に`!`つけた方がよさそう
- @haruguchi
- `validate do ~ end`の中にバリデーションの記述を書くと名前つけなくていいんだ。
- `book.errors[:name] << "I don't ..."`になってるけど、Railsのバージョン上げたらaddメソッドでエラーメッセージ追加してねっていうwarningが出た記憶がある
- !ありだと失敗時に例外出るけど、よく考えたらfindは!なくても例外が出るなぁ :naruhodo:
- @garammasala29
- `reload`はレコード再取得
- 「!」を伴うメソッドはバリデーション失敗時に例外(ActiveRecord::Recordvalid)が起こる
- バリデーションの種類たくさん
- @niikz
- ヘルパーで簡単にバリデーションできて便利
- エラーメッセージが複数ある場合は配列で返ってくる
### 本日の振り返り(よかった点・次回に向けての改善点等)
- @fugakkbn
- たまには開始時間から参加したいがなかなか難しい。
- @maimu_x2x
- やっぱり読み手で参加すると頭に入ってくる度が違うため、間に合えばまた読みながら参加したいと思います! :waiwai::yatta-!: :+1: :sasuga!:
- @niikz
- 初司会でしたがみなさんに助けてもらって楽しくできました!😊 :waiwai:
- @fugakkbn :+1:
- @napple29
- niiさんの司会、全然初めて感なかったです
- いつもガラムマサラさんがドライバーしている、ナイスです、いつもありがとうございます!
- @garammasala29
- haruguchiさんお仕事どうですか〜?
- 生きてます!:muscle:
- @haruguchi
- リングフィットアドベンチャー
- ダイイングメッセージかな…
- 仕事始まったばかりなのに😭(笑)
- @saki
- niiさんとガラムマサラさん、ありがとうございました🙏✨
-----
## 2022\-08\-04(木)
### 連絡事項や確認・相談
### タイムキーパー
### ドライバー
### 読んだところ
p.69[2-2-4 コールバックによる制御]~
### 次回
P.73[2-2-5 ActiveRecord::Enumで列挙型を扱う]~
### 先輩が教えてくださったこと
### 自由に使う共有スペース
#### 今日エラーが発生した際に入力したコマンドの流れ
- コードを試そうと思ったらエラー!(Publisherに`id`が`1`のデータはない)
```ruby=
irb(main):007:0> Book.create(name:"We Love Cat", publisher:Publisher.find(1), price:999)
ActiveRecord::RecordNotFound (Couldn't find Publisher with 'id'=1)
```
- Publisherにデータを作る。
```ruby=
irb(main):003:0> publisher = Publisher.new
irb(main):004:0> publisher.name = "alice"
irb(main):005:0> publisher.address = "Tokyo"
irb(main):006:0> publisher.save
```
- 5000円以上のBookモデルをDestroyしようとした際には警告がでるコールバックを確認したかったけれど、エラーが発生!
```ruby=
irb(main):001:0> book = Book.create(name:"High Price Book", publisher: Publisher.find(1), price: 10000)
(0.6ms) SELECT sqlite_version(*)
Publisher Load (0.3ms) SELECT "publishers".* FROM "publishers" WHERE "publishers"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) begin transaction
Book Create (0.5ms) INSERT INTO "books" ("name", "price", "created_at", "updated_at", "publisher_id") VALUES (?, ?, ?, ?, ?) [["name", "High Price Book"], ["price", "10000"], ["created_at", "2022-08-04 09:28:03.311901"], ["updated_at", "2022-08-04 09:28:03.311901"], ["publisher_id", 1]]
(0.7ms) commit transaction
=> #<Book id: 4, name: "High Price Book", published_on: nil, price: "10000", integer: nil, created_at: "2022-08-04 09:
irb(main):002:0> book.destroy
(0.2ms) begin transaction
Book Destroy (0.8ms) DELETE FROM "books" WHERE "books"."id" = ? [["id", 4]]
Book is deleted: {"id"=>4, "name"=>"High Price Book", "published_on"=>nil, "price"=>"10000", "integer"=>nil, "created_at"=>Thu, 04 Aug 2022 09:28:03 UTC +00:00, "updated_at"=>Thu, 04 Aug 2022 09:28:03 UTC +00:00, "publisher_id"=>1}
(0.7ms) rollback transaction
Traceback (most recent call last):
3: from (irb):2
2: from app/models/book.rb:43:in `high_price?'
1: from app/models/book.rb:43:in `>='
ArgumentError (comparison of String with 5000 failed)
```
- schema.rbを確認したら"price"の型が`string`になっていた!
- rollbackして修正しようと試みたがエラー、
マイグレーションファイルを5つ分戻すコマンド
```ruby=
❯ rails db:rollback STEP=5
```
- 直近のマイグレーションファイルをmigrateするのを忘れていたのか、`rails db:migrate:status`でmigrateの様子を見るとdownがひとつある。
```ruby=
❯ rails db:migrate:status
database: db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20220804081533 Create books
up 20220804082426 Create publishers
up 20220804082453 Create authors
up 20220804082608 Add publisher id to books
down 20220804083238 Create book authors
```
- 取り急ぎ、新しいマイグレーションファイルを作成して対応することにした。
コマンド
```ruby=
❯ rails g migration ChangeBookPriceToInteger
```
`db/migrate/20220804093559_change_book_price_to_integer.rb`内の記述
```ruby=
class ChangeBookPriceToInteger < ActiveRecord::Migration[6.0]
def change
change_column :books, :price, :integer
end
end
```
ファイル保存後、`rails db:migrate`を行って"price"カラムの型を`integer`に変更完了。
コードの確認もうまくできた。
- niiさんから教えていただいたこと
- 「ターミナルだけではなく`log/development.log`にもコンソールで実行したログが出ているので確認できる」
### 各自の疑問点や気づき、学んだこと
- @saki
- `before_validation do~end`で書く方法と、メソッドを定義して`before_validation :メソッド名`する書き方がある(🤔後者の方がすっきり書けて良さそう)
- `rails c`で`price`が`string`になっているのに、createする時`price: 10000`のようにIntegerで渡しても、自動的にStringになる挙動になっているのは知らなかった! 結構ハマリポイントな気がします
- カラムのデータ型を変更したい時
```ruby
$ rails g migration change_datatype_カラム名 _ of _ テーブル名
def change
# [形式] change_column(テーブル名, カラム名, データタイプ, オプション)
change_column :books, :price, :integer
end
```
- `after_destroy`の挙動:レコードを削除した後の処理を書く(※レコード削除しようとした時に発動ではなく、削除の処理後に発動)
- LEF (読めます!)
- コードがうまく反映されないときは、rails console を開き直せばうまくいくことが分かりました!
- ロールバックの仕方がすごく参考になりました! ありがとうございます🙏
- 最近、migrateについてよく分かっておらず、痛い目にあいました💦→[rails db:migrateしても変更が反映されなかった話(schema.rbが更新されずに苦しんだ話) | FBC](https://bootcamp.fjord.jp/reports/58375)
- @napple29
- プラクティスはコールバック処理なんて使わなかったのにチーム開発でコールバックと出会って最初意味がわからなかった記憶
- コールバックはとても便利だけど、コントローラーから離れているので、他人の書いたコードを見落とすと思わぬ事故が起こる
- マイグレーション関連は毎度コマンドと書き方をググっているので覚えられない、、shizimiさんに教えていただいた`rails db:migrate:status`は腕にタトゥー入れます
- @paru871
- コールバックでの警告のログを表示させたいとき
`Rails.logger.warn "~~"` と書くのを知った!
- コールバックは便利だけれど使い方がやっかいで思わぬ挙動になりがちな印象特に他のメンバーさんが書いたコードを的確に理解する、自分のコードも間違いが起こらないようにと意識していきたいです。
- @garammasala29
- マイグレーションコマンド、いい復習になった!
- `rails db:migrate:status`
- `cange_column, テーブル, 属性, データ型`
- コールバックのメリット
- 前後処理を宣言的に書ける
- 保存後に行いたいものの実行漏れを防げる
- @maimu_x2x
- 一度流したマイグレーションのロールバックや更新はやったことがないため、流れを見れて勉強になった。
- コマンド全然覚えられないため、すらすら出てくるのがすごい!!
- @fuwa
- マイグレーションの流れ勉強になります〜(いつも都度都度ググってました。。)
- コールバック処理初めて聞いたかも。便利そうだけどコールバックポイントによって発火する処理が違うので事故りそうな気もする。
- hikaru
- マイグレーションのコマンド勉強になりました!
- 細かく状態を監視するためのフックがあるんですね〜
- バリデーションは名前をつけておけば処理の内容が分かりやすくなって良さそう
### 本日の振り返り(よかった点・次回に向けての改善点等)
- hikaru
- Paruさんドライバーありがとうございました〜
- hack.mdが入力中に自動でスクロールされちゃってつらい...
- :wakaru:
- @maimu_x2x
- Paruさん、事前に準備くださり、ありがとうございました!
- コールバックの使い所がまだよく分かってないので、使うタイミングが来たらここを読み直そうと思います!
- @fuwa
- Paruさん準備していただいてありがとうございます〜
- 明日は毎月恒例前職の軽音部があるので出席できないかもです。明日なのに楽譜すら作れてないのやばい!
- @paru871
- 明日からはこのコードをベースに使っていろいろ試してみてもらえたらと思いました。
- あとで、今日入力したコマンドを上の共有スペースにまとめておきます。
- ドライバーをやっているとコマンドを思いつかない(のは言い訳ですね。。)みなさん、たくさんサポートしてくださりありがとうございました。
- わかりますよ!私もいつもしないミスをします!!笑
- @garammasala29
- Paruさん準備ありがとうございました!
- ワイワイとモブプロできるのたのしい
- @napple29
- 実際に動かすと勉強になりますね!Paruさんに感謝、、、!!!
- よいこは`rails`の前に`bin/`をつけよう!笑(つけない派)
- コントローラーがfatになるので正しく使えるとコールバックは便利
- @saki
- paruさんコードのご用意ありがとうございました!`bin/rails db:migrate:status`や `bin/rails db:rollback`勉強になりました
- Hikaruさん初司会ありがとうございました!こなれていらっしゃってスムーズでした👏
- わかる、慣れている感じがしました
- 本当にそう!
-----
## 2022\-08\-05(金)
### 連絡事項や確認・相談
#### ドライバーさんの操作手順
- PC内の都合の良い場所で下記のコマンドをターミナルから入力、ファイルをクローンしてコードをダウンロードする
```
$ git clone https://github.com/Paru871/book_admin.git
```
- ダウンロードできたら、ディレクトリbook_adminを VSCode などで開いて、ターミナルから下記のコマンドを1つずつ入力、これによりDBが初期状態となり、seedに入れたデータが入る(現在Publisherが1件)
```
$ bundle
$ yarn
$ bin/setup
$ rails db:reset
```
- その後、`rails s`してRailsを起動する。
### 読んだところ
P.73[2-2-5 ActiveRecord::Enumで列挙型を扱う]〜
### 次回
P.79 [2-3-1途中の「ビューの決定と表示」]〜
### 先輩が教えてくださったこと
### 自由に使う共有スペース
### 各自の疑問点や気づき、学んだこと
- @garammasala29
- enumはイーナム
- bootcampアプリでもenumはいくつか使われていた
```
enum emotion: {
sad: 1,
soso: 0,
happy: 2
}
```
- `rails g controller`便利だな〜
- hikaru
- enumは多機能でとても便利なのが分かりました〜!不正値ガードもできちゃうなんてとてもお利口
- コントローラやルーティング(ラウティング?)のあたりは理解がふわっとしているのでちゃんと覚えたいです...
- @maimu_x2x
- enumの仕組みをちゃんとわかっていなかったのでイメージが掴めた。まだ説明できるほどではないため、、、インデックス箇所に追加しました!
- @paru871
- enum型の存在を今日初めて知った!自作サービスを作りながら、こんな機能があったらいいなぁと思っていたけど探せなかったことを思い出した。
- enum型で定義しておけば、シンボル、文字列、数字のどれで渡しても同じものとして対応する値を保存してくれる(DB保存は数値)
- enumは述語メソッドで状態の問い合わせが可能。
- !をつけたメソッドでenum値の上書き更新が可能。
- コントローラの役割と動きの流れをしっかり見届けたい。
- @saki
- enum便利!
- 定数はたしか中身を結構簡単に書き換えられてしまうので、入る値が複数あるけど値も上限も決まってる時に使い勝手が良さそうと思った。
- コンソールで見た時は文字列なので人から見て分かりやすく、DBには決まった数字が入って、文字列が入るよりも管理しやすいので良いとこどりな感じがした
- bootcamp私も調べましたが、プラクティスの未着手/着手/提出/完了 でも使われてるっぽかった!
```ruby
class Learning < ApplicationRecord
enum status: { unstarted: 0, started: 1, submitted: 2, complete: 3 }
```
- `http://localhost:3000/books/1`にアクセスすると、paramsに`<ActionController::Parameters {"controller"=>"books", "action"=>"show", "id"=>"1"} permitted: false>`という情報が入る。`books/1`にアクセスしたので、paramsのidに1が入る。これを利用してboks_controllerのshowアクションで`@book = Book.find(params[:id])`と書くことで、Bookのidが1のレコードをインスタンス変数に代入できる
- @shizimi ※読み上げお願いします🙏
- 会社のコードを並行して確認してみたら、enumerizeがたくさん使われていることを発見。enumより圧倒的に、enumerizeのが使われてた。
- どう高機能なのか、どう便利なのか理解しながら使えるようになりたい
### 本日の振り返り(よかった点・次回に向けての改善点等)
- @maimu_x2x
- Railsを学習し始めた頃にparamsって何?!ってなって、Sinatraでやっと理解しました。今日読んだ部分も理解ができたのでよかったです!
- hikaru
- enumはenum、enum、enum などいろいろな派閥があるみたい
- イーナム、エナム、イニューム
- routeもrouteなんだよなあ、vue-router...
- @garammasala29
- パブリッシャー用意されててびっくり!さすがParuさん!
- @paru871
- paramsの正体不明感が薄まって怖くなくなったー。ガラムマサラさんのおかげ!ありがとうございました🙏
- 今週も楽しかったです。
- @saki
- やっぱり手を動かして色々試せるのは楽しい&学びになりますね! Paruさんありがとうございます🙏✨✨
- ドライバーやってる時に入力を待ってくださっててやりやすかったです!ありがとうございます🥰
-
-----