# 【第2週】パRails輪読会🚂 \(2023\-08\-28\~ 2023\-09\-1\) ###### tags: `パRails🚂` - [開催概要](https://hackmd.io/4A_8ahJtQNi5hz713N5Y7w?view) - [パRails輪読会 ノートまとめ]() - サンプルコード・正誤表:[サポートページ:パーフェクトRuby on Rails【増補改訂版】:|技術評論社](https://gihyo.jp/book/2020/978-4-297-11462-6/support) - **サンプルコードをダウンロードしただけでは、すぐに`rails s`できない可能性が高い**です。 以下のページに環境構築の手順をまとめたので、ドライバーをやってくださるという方は、こちらに沿って環境構築をお願いします🙏 ⏩ [環境構築の手順 2022年版](https://hackmd.io/y7qb2BRMT2Wd4tAtKYObcQ) ⏩ [環境構築の手順 2023年版](https://hackmd.io/3_lnn8_QRD6wEjwFbWcBzQ) 💁‍♀️ [更新の手順 2章編](https://hackmd.io/pZAmF2EjSmyQ38lUtJ_CqA) ## 目次 [TOC] ------ ## 2023\-08\-28(月) ### ファシリ 今日は特になし ### ドライバー @moegi29 ### 読んだところ ### 次回 二章の51pから。🚂 ### 学んだこと・感想 - @sharoa - 今日は本の内容とは違うところで勉強になった。 - 前に勉強していた時のノートを引っ張り出してきて、それを横目で見ながら見ていましたが、 - gitも時々勉強しなおしたいな、と思いました。(忘れてることがある。) - moegiさんドライバー本当にありがとう✨ - 兎にも角にも、ちゃんと動かせそうなので明日から楽しみです。 - @odentakashi - みんなで作ってく感がとっても楽しいなと思いました。 - リポジトリを作るタイミングは他のコマンドとかと違って使う頻度が少ないので、なかなか覚えられずいつも調べてる気がします。 - @shodan - git / github の勉強になりました。 - 自分で一からリモートリポジトリを作ってプロジェクトを進める場合、他のメンバーにそのリポジトリにpushしてもらうにはコラボレータ設定を行う必要がある。 - https://blog.qnyp.com/2013/05/28/pull-request-for-github-beginners/ の意味をやっと理解したような気がする。 - @sadanora - `$ rails new`できてよかった🎉 - `rails new`したときに階層がひとつ下になるのが嫌で色々試行錯誤したのを思い出しました。 - `$ git remote add`でリモートの設定変えればよいというのが勉強になりました。 - 人のリポジトリにpushするにはコラボレーターに追加する必要がある。 - @djkazunoko - gitの基本的な操作だったが、人の画面見ながら喋りながらやると結構訳わからなくなった - @hiromisugie - 皆さんでワイワイとリポジトリの準備をできて楽しかった&勉強になりました! - Cloneしたファイルで`rails s`すると、自分の手元だとYarnのエラーが出ているので涙、解決を試みてみます。 - gitは本当に慣れない&実行するときの恐怖がすごいので、少しでも慣れていきたいです。 - @motohiro-mm - `git add . `で全部ステージングされる - GitHubではCollaboratorsにユーザーを入れると他の人がそのリポジトリにpushできるようになる - `git remote add`でリモートの設定がかわる - ドライバーの人は最初だけ`git clone`しておいて次回以降は`git pull`でやっていく - Gitの理解がそもそも乏しいなと今日思ったので、復習しておこうと思いました。 - moegi - 自分でリポジトリを作成~rails newしてみんなをinviteする流れを経験できて良かった - `git push origin https://github.com/KMZ0209/Perfect_Ruby_on_Rails_Ch2` でクローン先にpushできるの知った - gitの操作は毎回ググりながらやっていて全然慣れないのでこれを機にいろいろ触って慣れていきたい - みなさんたくさん教えてくださりありがとうございました! - @cellotak - githubのリポジトリを複数人で利用するときの知見を得られた! - 空のリモートリポジトリを作る - ローカルでrails new する - ブランチがデフォルトがmasterなのでmainに変更する - git remote add で空のリモートリポジトリを設定する - pushする - 他の人はコラボレーター?に追加してもらって、cloneすると、変更をpushできるようになる。 - Discordの画面共有で音付きのリアクションができるの初めて知りました。 - @moegi29 さんドライバーありがとうございます! ------ ## 2023\-08\-29(火) ### ファシリ @shodan ### ドライバー @hiromisugie ### 読んだところ 2-2 モデルを扱う / ActiveRecord::Relationについて まで ### PR https://github.com/KMZ0209/Perfect_Ruby_on_Rails_Ch2/pull/3 ### 次回 2-2 モデルを扱う / scopeを定義する から ### 学んだこと・感想 - @sharoa - 感想になってしまいますが、全てが新鮮でした。 - `rails c`で`irb`がたちあがるのも初めてしった。 - railsではないけど、gitのbranchでいまいるところを@でできるというのはびっくりしました。いいこと聞きました✨ - @odentakashi - `where`を使って返ってきた`ActiveRecord::Relation`のインスタンスに`Array`クラスのメソッドが当てられなかったことを思い出しました。 - `ActiveRecord::Relation`のインスタンスはこういうSQLを発行するよみたいな感じ? - @shodan - findのid検索で見つからなかったら例外、というのは今日自分のプラクティスを進める中でちょっとハマったところだったのでタイムリーでありがたかったです。 - find_byで見つからないなら`nil`とか、微妙にややこしい。 - @moegi29 - ActiveRecordによるモデルにはDBと接続してレコードとActiveRecordオブジェクトを結びつける。バリデーション、レコード保存時などに実行するさまざまなコールバックなどを実行する役割(ビジネスロジックの実装的なふるまい)がある。 - Book.where("price > ?", 3000)[0],Book.where("price > ?", 3000)[1]を試して頂いて配列風で返ってくるということがわかった - git push origin @ →今いるブランチにpushできる - @sadanora - findメソッドで検索対象が見つからない場合はActiveRecord::RecordNotFound例外が発生する。find_byの場合はnilが返る。 - whereメソッドで条件に対してデータが存在しない場合は空のActiveRecord::Relationインスタンスが返る(例外は発生しない) - git push origin @ - 便利! - @motohiro-mm - ActiveRecord::RelationはActiveRecordのQueryInterface による操作結果をオブジェクトとして表現したもの - 内部はどのようなSQLを発行するか、という情報だけもつ - 実際にSQLの実行結果が必要になるまでDBへのアクセスは発生しない - レコード検索すると単数ではモデルクラスのインスタンス、複数はActiveRecord::Relationのインスタンスが戻り値になる - pushするときに@で今いるブランチをpushできる`git push origin @` - push するところも見れて今後の流れがよくわかりました - @hiromisugie - `find`メソッドはidを使って検索する、`find_by`メソッドは作成したカラム(nameやprice)を使って検索する - `find`メソッドで見つからない場合は`ActiveRecord::RecordNotFound`が返り、`find_by`で見つからない場合はnilが返る。それぞれ異なるので覚えておきたい。 - 複数のレコードを検索するときは`where`メソッドを使う。その際、結果は`ActiveRecord::Relation`というクラスのインスタンスが返ってくる。これは配列風のオブジェクト。(風とは…と思ったけど、to_aで本当の配列になるところでなるほどと思った) - `git push origin @`で今いるブランチのプッシュができる(別の輪読会で得た知見をシェアできてよかったです。今いるブランチを勘違いしていないかだけご注意です) - ドライバーの練習できて良かったです!(この後どんどん難しくなっていきそうなので早いところ一度やっておくのオススメです笑) - @cellotak - `find`メソッドや`find_by`メソッドでは1件のレコードをインスタンスとして取得できる - `.カラム名`で情報を抜き出せる - `where`メソッドでは複数件のレコードを取得でき、配列「風」のオブジェクトが返ってくる - 配列と同じく番号で呼び出せることは確認できた - どこが配列と違うのか気になった - RailsコンソールでActiveRrcordのメソッドを実行する場合、`.to_a`をつけるときとつけないときのSQLの実行タイミングの違いが分からなかった。 - pushするときにブランチ名を`@`にすると現在のブランチをpushできる - @djkazunoko - gitの`@`は`HEAD`のaliasのはず ------ ## 2023\-08\-30(水) ### ファシリ @cellotak ### ドライバー @moegi29 ### 読んだところ 2-2 モデルを扱う / scopeを定義する から 59pのコラム「デフォルトスコープに注意」まで。 https://github.com/KMZ0209/Perfect_Ruby_on_Rails_Ch2/pull/4 ### 次回 2-2-2 モデル同士のリレーションから。🚂 ### 学んだこと・感想 - @sharoa - 今日も難しい。 - でも、`find_by`はクラスメソッドで定義した場合は`nil` をかえすけど、`scope` で定義すると結果が`nil`となった場合は該当`scope`の検索条件を除外したクエリを発行し、必ず`AvtiveRecord::Relation`を返すということはなんとなく理解できました。 - 挙動が異なることに注意していきたい。 - @hiromisugie - モデル内で`scope`を定義できる。これはよく利用する検索条件に名前をつけてひとまとめにしておける。 - `find_by`で該当するものがない場合は`nil`が返るが、`scope`の定義で`find_by`を使うと、`nil`が返るのではなく、その条件自体がなかったものとして返る??ので、`scope`を使った場合と使わない場合とで結果が異なってくるので、注意が必要。`scope`は便利だけど意図しない結果になることがあるから注意しましょうねということと理解しました。 - @motohiro-mm - scope:よく利用する検索条件に名前をつけてひとまとめにしたもの - findやfind_byのように条件が合致しなければnilを返すものを、scopeで定義すると結果がnilのとき検索条件を除外したクエリを発行して必ずActiveRecord::Relationを返すので注意! - 分かりにくいところを皆さんが解説してくださって勉強になります。 - @shodan - `scope`で定義した検索条件は、結果が`nil`になったときはその`nil`を引き起こす条件を除外した結果(つまり、なにかしらの`ActiveRecord::Relation`オブジェクト)を返す(?)仕様。 - そのせいで、結果がなかった場合`nil`を返す`find_by`を組み込んだ`scope`を定義すると、意図と異なる挙動をするときがあるので注意が必要。 - シンプルにややこしいですね……。 - @sadanora - scopeの結果がnilとなった場合は該当Scopeの検索条件を除外したクエリが発行され、ActiveRecord::Relation オブジェクトを返す。 - クラスメソッドでfind_byを使った場合にnilが返るのに対し、直感と反する動作になるので注意。 - わかったような、わからないような感じでまだ少しモヤっとしますが、その分この挙動は印象に残りました笑 - @moegi29 - Book.find_by(price: 10000)→nilが返る、Book.find_price(price: 10000)→ActiveRecord::Relation返る等いろいろ試したことでなんとなくイメージができた気がする。 - 挙動の違いがややこしくて難しい。 ----- ## 2023\-08\-31(木) ### ファシリ @sadanora ### ドライバー @moegi29 ### 読んだところ 2-2-2 モデル同士のリレーションから63pの途中まで。 今日のPR: https://github.com/KMZ0209/Perfect_Ruby_on_Rails_Ch2/pull/5 ### 次回 二章63p「多対多のリレーションを実現する」から。🚂 ### 学んだこと・感想 - @sharoa - 色々と作成する手順を見れてすごくよかったです。 - 改めて自分がやる時には今日のことを思い出したいな、と思います。 - `rails db`のところが最終的にきちんとできてよかったです。今後のためにエラーの内容は覚えておく。 - @shodan - まさに今のプラクティスで関連付けについて色々と学習しているところだったので、勉強になりました。 - Windows,UbuntuはデフォルトでSQLite3が入っていないかもなので、別途DBする必要がある。 - `rails db:reset`は新しくテーブルを作り直すコマンド。 - @odentakashi - SQLiteが入っていなかったのに動いていたのはどうしてなんだろうと気になりました。 - has_many :books <- 複数形、belongs_to :publisher <- 単数系 - @motohiro-mm - referencesは別のモデルを参照を意味する - 1:多のイメージがわかりやすかったです - 最近Railsの課題でこういうのやったなぁ…ってしみじみ思いました - @hiromisugie - 作成ずみのモデルに対して関連づけをする場合は`rails g migration AddPublisherIdToBooks publisher:reference`みたいに書く。`rails g migration`にまだ慣れないので慣れたい - `has_many`もしくは`has_one`と`belongs_to`について改めて確認できました - リレーションを作成することで、`book.publisher.name`のように書籍モデルから出版社モデルの情報を取ってくることができる - @sadanora - SQLite3ではnot null制約を付与しつつカラムのデフォルト値を指定しない場合、カラムの追加でエラーになる - `add_reference`で参照を追加できる - `has_many`と`belongs_to`によって1対多を表現できる ----- ## 2023\-09\-1(金) ### ファシリ @sharoa ### ドライバー @sadanora ### 読んだところ 二章63p「多対多のリレーションを実現する」から 68pの途中まで。 今日のPR: https://github.com/KMZ0209/Perfect_Ruby_on_Rails_Ch2/pull/6 ### 次回 第二章の68p、「バリデーションと「!」付きのメソッド」から。🚂 ### 学んだこと・感想 - @sharoa   - 久しぶりに読んだ気がするw   - めちゃくちゃドキドキしました。   - 「1対多、多対1、1対1、多対多」の関係がある。   - 沢山知らない言葉がでてくるので新鮮なのと、これまた緊張が走ります。 - @odentakashi - validationとDB制約を併用する方が良い。 - validationはレースコンディションですり抜けてしまう可能性があるため。 - @motohiro-mm - 多対多は中間モデルを作成する - has_manyとthroughで中間モデルを定義 - データを関連付けするときに、bookからとauthorのどちらからでもできる - バリデーションはデータをsaveするときに戻り値falseになってエラーになる - 保存せずにバリデーションだけしたいときは`valid?`をつかう - 今プラクティス課題でバリデーションを使ったりしていて苦しんでるので勉強になりました - @hiromisugie - 多対多はお互いのモデルでお互いを`has_many`すると共に、それぞれで中間テーブルを`through`することで設定できる - 多対多の定義をすると、両側から登録できる(「この人の書いた本はこれ」という登録方法と、「この本の著者はこの人」という登録方法) - DBへの保存を行うにあたり、createメソッド一つで引数にいろいろな情報をまとめて入れて保存する方法と、変数を定義して1つ1つの情報を入れて行って最後にsaveメソッドで保存する方法がある。 - バリデーション用のメソッドをバリデーションヘルパーと呼び、モデルの中に書く。 - 保存に失敗した時、失敗の理由がインスタンスに記録され、`.errors`でエラー内容を呼び出すことができる。`.errors.full_messages`だと人間が読みやすい形式で呼び出せる。 - 保存をせずにバリデーションだけ行いたい場合は`.valid?`メソッドでできる。 - レースコンディション=Race Condition/競合状態 - https://enterprisezine.jp/securityonline/word/detail/%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3 - @moegi29 - 多対多を表現するには中間モデルの作成が必要。ActiveRecordが中間テーブル作成や情報をキーにしたデータの取得をしてくれる。 - モデルのバリデーションでは多くの検証ができるが、レースコンディションですり抜けてしまう問題もあり得る。notnull制約やDB上で利用できる制約は活用したほうが良い。 - @sadanora - 多対多を表現するには、has_manyのオプションthroughtで中間テーブルを指定する。 - dbコンソールで`.mode line`を使うとSQLite3は出力結果をみやすくできる。 -----