# 【第19週】パRails輪読会 \(2022\-11\-28\~ 2022\-12\-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) - [パRails 環境構築の手順](https://hackmd.io/y7qb2BRMT2Wd4tAtKYObcQ) ## 目次 [TOC] ------ ## 2022\-11\-28(月) ### 連絡事項や確認・相談 ### タイムキーパー - @fuwa ### 読んだところ - P. 481 [12-2-2途中 ■ActiveModel::Validations]〜 ### 次回 - P.490 [12-3-4途中 ■ ActiveModel::Validator] ありがとうございます!! ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - @garammasala29 - `~=`でマッチング - クラスの切り出し方がなるほどなぁと思いました。依存関係の意識 - ActiveModelのモジュール便利。大規模なアプリではたくさん使われているんだろうなぁ - dawa - 便利なものがあるんだなということでしょうか。実際試してみるともっとわかるでしょうか。 - @fuwa - フォームオブジェクトを使うとモデルの処理を分割できる - モデルみたいなやつ、っていうざっくり理解でいいのかな? - `ActiveModel::Vaidations::Callbacks`は乱用するとコールバックまみれになるので注意しましょう。あんまり使わない方がよさそう - hikaru - `before_validation`とかを使いたかったら`::Callbacks`もincludeしよう - こんな感じでちょいちょいモジュールとしてインクルードして便利機能が使えるということを覚えておきたい - モデルからフォームオブジェクトに分離するとDRYになって良い - `=~`はマッチすれば真を返すらしい(チェリー本2 p.211) - @tomonari - 管理者がCSVファイルから一括でユーザー登録する場合も考えて、フォームオブジェクトを作るといいんですね。 - フォームオブジェクトはメソッド以外の記述が多いですね。 - Saki - フォームオブジェクト:モデルの処理を分割することができる - ActiveModelのモジュール使ったことないけど便利そうなので使ってみたい - コールバックはできれば使いたくない - @haruguchi - コールバックのxxx_commitはレコードの作成・更新・削除時にフックされるやつ - https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - @fuwa - チーム開発で今日も何から手をつければいいかわからないまま時が流れました - 今日もバイトでした。喋らずもくもく作業していたのでテンションがまだ上がっていないようです - dawa - 昨日はharuguchiさんにペアプロお願いして進むことができました。本日レビューが返ってきたので、またもくもくしていきます。 - :ガンバー: がんばります〜 - @garammasala29 - 意気揚々とリハビリにいったら予約は明日でした - 今日からHerokuが有料化になって元々課金したから大丈夫だろうと思っていたらSSL証明書が期限切れになっていた - herokuのやつ何もやってないや…代わりにやってくれ - Saki - 低気圧なせいか体がだるいです〜 - hikaru - バイトでジム代を浮かすというライフハックを得ました - @haruguchi - 11月終わるぞ! - 😱 - 今年終わるぞ! ------ ## 2022\-11\-29(火) ### 連絡事項や確認・相談 ### タイムキーパー - Saki ### 読んだところ - P.490 [■ ActiveModel::Validator]〜 ### 次回 - P.495 [13章 複雑なデータ操作を実装する]〜 ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - hikaru - `ActiveModel::Validator`は複数の属性を組み合わせたバリデーションなどに使う - 特定の属性に依らないエラーを追加する場合は、`:base`という属性で`errors.add(:base, messages)`のように追加する - プレゼンター:ビューに渡すオブジェクトを単位にしてロジックを実装する - デコレーターパターンで実装されているのでデコレーターとも呼ばれる - ビューヘルパーは名前がかぶる、インスタンスメソッドはモデルが肥大化する - @fuwa - プレゼンターはビューに渡すオブジェクトの単位で表示に関するロジックを整理できる - デコレーターはチーム開発で見かけていたので気になっていました - `ActiveModel::Validator`は複雑なバリデーションを定義できる。 - @garammasala29 - `ActiveModel::Validation`と`ActiveModel::Validator`は別物。複数の属性を組み合わせるなど、より複雑なもの - デコレーターの存在は知っていたけど、どういう場面で使えばいいのかわからなかったので勉強になった - 複数のコントローラー間で利用したいビューヘルパー。ビューの中でしか利用できない。 - 呼び出しのタイミング3つを後で読む - [amatsuda/active\_decorator: ORM agnostic truly Object\-Oriented view helper for Rails 4, 5, and 6](https://github.com/amatsuda/active_decorator#features) - Saki - Validatorを自作する時は、`:base`を使って、オブジェクト全体で共通のバリデーション(~is invalidとか)のエラーを作ったり、カラムを指定して特定のカラムで発生するエラーを作ったりできる。 - [Active Record バリデーション \- Railsガイド](https://railsguides.jp/active_record_validations.html#errors-add) - ビューヘルパーの問題点 - ロジックやモデルを作っただけではだめで、画面に表示するための処理が必要。 - Helperにビューヘルパーを自作すると、すべてのコントローラのビューで使えてしまう。 - つまり、名前が重複しないようにしないといけない! - この問題に加えて、 - @tomonari - 表示関係のロジックはモデルとかヘルパーではなく、プレゼンター(デコレーター)で実装すべきなんですね。あと、なんでプレゼンターなんでしょうね。 - presentation:「見た目、体裁」ってことですかね? - なるほど〜 - カスタムバリデーションは便利そうですが結構難しいですね。optionsをオーバーライド(?)したりとか。 ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - Saki - haruguchiさんが作ってくださったPRはいらっしゃった時に動かしてみようと思います〜 - @fuwa - 今日はいい肉の日だったのにガン無視してしまいました - hikaru - 今日は言いにくいことを言う日らしいので言うんですけど、僕の誕生日なので祝ってください!!! - えーめでたい。おめでとうございます!!!!!!!!!!!!:cake: - おめでとうございます!!!!!!!!:cake::cake::cake::cake::cake::cake: - めでたい!!!!!!:birthday:birthday::birthday::birthday: - :祝: - @garammasala29 - 今日はジンギスカンにします ------ ## 2022\-11\-30(水) ### 連絡事項や確認・相談 ### タイムキーパー - ガラムマサラさん ### 読んだところ - P.495 [13章 複雑なデータ操作を実装する]〜 ### 次回 - P.501 [13-1-4 ■ モジュール間の依存関係の解決]〜 ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - @maimu_x2x - `Class.new`はクラス定義の別の書き方。 - `Concern`を利用すると特定の概念や機能に関するロジックをモデルやコントローラーとは分けて実装が可能になる。 - 複数のモデルやコントローラの間で再利用が可能になる。 - `Module` のメソッドをクラスメソッドとして使うには `class_methods` を使う。 - @garammasala29 - Concernを使うことで複数のモデルやコントローラで処理を再利用できる。概念としてはなんとなく理解。チェリー本のモジュール章を読み直す - `ancestors`メソッド便利! - hikaru - 書き換える前のコードがわからないという罠にはまった - `ActiveSupport::Concern`をクラスにextendして`included`と`class_methods`というメソッドを利用して色々できる - `included`に渡したブロックは`ActiveSupport::Concern`をextendした先のクラスやモジュールで実行されるみたいな感じ - `class_methods`の中に定義したメソッドが`ActiveSupport::Concern`をextendしたクラスやモジュールのクラスメソッドとして使えるようになる - `Bar = Class.new { include Foo }` - Saki - Concernは、とあるモデルで使っているメソッドを別のクラスでも使いたい時に、Concernディレクトリにモジュールとして切り出すことで再利用できるようにする - 肥大化したモデルの見通しを良くするために、見かけのコード量を減らすという使い方もできてしまう。→このように定義したConcernは、特定のモデルと結びついていて再利用できない&他のConcernで定義された変数やメソッドを頻繁に利用していると、コードの見通しはむしろ悪くなってしまう - `Class.new`は、Classクラスのインスタンスを作成している - @tomonari - FBCのconsernを見てみると、tuggableの他searchable、commentableなどがありますね。モデルを跨いで使うようなロジックを~ableという形で切り出してるんですかね。 - @haruguchi - class_methods初めて知った - 実装自体は比較的シンプル!!!! ```ruby= def class_methods(&class_methods_module_definition) mod = const_defined?(:ClassMethods, false) ? const_get(:ClassMethods) : const_set(:ClassMethods, Module.new) mod.module_eval(&class_methods_module_definition) end ``` - LEF - 無名クラスについて初めて知りました! - [Ruby で無名クラスを定義する - Secret Garden(Instrumental)](https://secret-garden.hatenablog.com/entry/2015/05/30/000000) - パRubyとか詳しく書いてますよ! ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - @maimu_x2x - お弁当宅配のNoshはおかずの数としてはちょうどよく味も美味しかったです! - 気になる:eyes: - JS分からなすぎてUdemyの集中講座買って勉強しています。 - パRailsの輪読会が終わったら木金の19時からJSPrimerの輪読会やろうか考え中です・・・ - これも気になる:eyes: - @garammasala29 - 札幌は雪が積もりました - Hikaruさん、誕生日いかがでしたか? - :birthday: - バイトとテニスで疲労が溜まりすぎて吐きそうになりました... - Saki - ここ数日あたたかくて日中は暖房いらずですね〜 - チェリー本また読み返さないとな〜 - そういえば一時期「Noshのある人の生活、無い人の生活」、みたいなCMよく流れてましたね〜 - 滋賀(田舎)にあるんかな?:eyes: - 職務経歴書なかなか完成しなくて焦ります😅 - 時間かかりますよね・・・FBC側でフィードバックとかはあるんですか? - ありがとうございます!お願いすれば添削してくださいますね!まだそこまで行けてないですが😅 - LEF - webセキュリティむずかしい…… - 20:00からのよかじさんのストレッチ企画が気になってます👀 - hikaru - 一人カラオケしてきました〜声がガラガラになりました〜 🎙 - 今日噛み噛みだったな... - @haruguchi - 読みたい本がありすぎて1日48時間くらい欲しい - wakaru👀 - 筋トレ始めました。いや、筋トレをしようかなと検討を加速させ始めました。 - @tomonari - 明日から12月ですね。アドカレ書かないと… ------ ## 2022\-12\-1(木) ### 連絡事項や確認・相談 ### タイムキーパー hikaru ### 読んだところ - P.501 [13-1-4 ■ モジュール間の依存関係の解決]〜 ### 次回 - P.506 [13-2 コールバックオブジェクト]〜 ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - @garammasala29 - `extend ActiveSuport::Concern`を使えばモジュールの中でモジュールを使いたいときなど、モジュール間の依存関係をよしなにやってくれる - ルートの共通化でconcernが使える。独習Railsはルーティングが詳しいので結構参考にするけど、働き始めたらあまり触らなくなる? - @fuwa - `ActiveSupport::Concern`を使うとモジュール間の依存関係が適切に解決できる - ただし依存関係にある全てのモジュールで`extend ActiveSupport::Concern`する必要がある - concernメソッドを使うと共通のルーティングを定義できる。読みやすくなりそう。 - 昨日ほとんど参加していなかったのでconcernよくわかってないです〜。。 - @dawa - consern: routingがわかりやすくなるのであれば使ってみたいなと思いました。 - @tomonari - module内で別のmoduleをincludeすると、クラスメソッドが別のクラスに追加されてしまう。ActiveSupport::Concernを使うとこうした依存関係の問題を解決できる。なぜかは分かりません。 - routingでもconcernが使えます。 - hikaru - RailsAPIでもモジュール間の依存関係の解消はパRailsと同じくらいのことしか書かれていないみたいでした - - Saki - concernはルーティングの共通化でも活躍。以下が分かりやすい。大規模なアプリケーションは共通化でコードを減らすことが大事そう。 - Railsガイド:[Rails のルーティング \- Railsガイド](https://railsguides.jp/routing.html#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E3%80%8Cconcern%E3%80%8D%E6%A9%9F%E8%83%BD) - 独習Rails - Concernは、モジュール間の依存関係を解決できる - 自作サービスレベルだとここまで複雑なことはしないのでコードが難しかった...!就職して理解できるようになりたい。 ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - @fuwa - バイトがホワイトでびっくりしてます〜 - 🎉 - アドベントカレンダー、輪読会はいいぞという話か反り腰の話かで悩んでいます - 輪読会いいぞの話きになる...!ヤッター :gogo: - @dawa - 急に寒くなり冬って感じですね。 - @garammasala29 - アドカレ悩む!こういうときに技術への興味って大事だと思わされる - 説明が絶望的に下手なので直したい - そんなことないですよー! - Saki - 今年が終わるのは名残惜しいですが、アドカレが始まって寂しくないです! - 微妙に明日で読み終わらないかもですね😅 - hikaru - 12月だ! - パRails輪読会終わってしまうの寂しいな - 🥺 - @tomonari - Vueでモーダルのコンポーネント使ってる例どなたかご存じないですか? - パRailsもあと7pで終わりですかね。 ----- ## 2022\-12\-2(金) ### 連絡事項や確認・相談 - 備忘:haruguchiさんのコールバックのPRモブプロ! - 来週月曜やるので来てくださいね〜! ### タイムキーパー - tomonariさん ### 読んだところ - P.506 [13-2 コールバックオブジェクト]〜 ### 次回 - 今日が最終回(?) ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - @maimu_x2x - 難しいけどharuguchiさんの解説でざっくりイメージは掴めました。ありがとうございます! - `#tap` は`each` のオブジェクト版で `#then` は`map` のオブジェクト版。 - オブジェクト版というのは新しい配列を作成して返すとかではなく、元のオブジェクト自身を更新しているためという理解。 - @garammasala29 - コールバックメソッドをカプセル化したクラスをつくれば再利用が簡単にできる - 加えてConcernもつかえばモデルやコントローラーから分離できるので肥大化防止につながる - @fuwa - コールバックオブジェクトを導入することで、モデルにコールバックを実装して肥大化させてしまうことを防げる - 保守性低下を防ぐために、コールバックオブジェクトを単体で利用するのではなくConcernと併用するのがオススメ - 更新系(updateとかcreateとか)の場合、Concernよりもコールバックオブジェクトの方がオススメ。テストを書きやすいので。 - hikaru - Concernをextendしつつコールバックオブジェクトにコールバックの処理を分離しておくと、そのコールバックを使いたいモデルでコールバックオブジェクトをincludeすることですっきりロジックを分けられる - @tomonari - 暗号化もcallbackやconcernで切り分けておくと色々なところで使えて便利。 あとは難しくて:cry: - @haruguchi ```ruby= # procは処理をオブジェクト化したもの(どちらかというと関数的な扱い方) add = Proc.new { |a, b| a + b} # 呼び出す時はcallメソッドや[]メソッドを使う add.call(1, 2) #=> 3 add[1, 2] #=> 3 # Methodオブジェクトはレシーバを固定させたメソッドをオブジェクト化したもの upcase_method = 'aaa'.mehtod(:upcase) # 呼び出し方のインターフェースは同じ upcase_method.call #=> 'AAA' upcasse_method.[] #=> 'AAA' # send 'aaa'.send(:upcase) send(:puts, 'aaa') # sendと__send__の違いはobject_idと__id__との違いと同じ ``` - tap, thenはめちゃくちゃ使う(めちゃくちゃは言い過ぎ) - Saki - コールバックオブジェクトの代わりにConcernを使うこともできる - 13章はRailsの機能というよりRubyのコードが難しかった - `then`は、`map`のオブジェクト版 ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - Saki - haruguchiさんご解説ありがとうございました〜!以前作ってくださったPRのモブプロをしたいのですが、月曜っていらっしゃいますか?? - 初めから行けるかわからないんですが、後半は行けます! - お仕事ありますもんね!ありがとうございます🙏✨ - Appendixはよく見たらwindowsの環境構築なので読まなくていいかなと思ってます〜 - 職務経歴書だいたい書き終わったんですが、不安なので誰かに読んで欲しいです😇 - @maimu_x2x - 最近仕事で落ち込みまくっていたため輪読会に参加できて元気出せました。:cake: :waiwai: - 明日のRailsGirlsのLT頑張ります! - :muscle: - 発表がんばってください!! [Rails Girls Gathering Japan 2022 \- railsgirls\-japan \| Doorkeeper](https://railsgirls-japan.doorkeeper.jp/events/146236) - @fuwa - 寒くなってきたのでそろそろ暖房をつけようか考えています - 既に絶賛暖房に頼り中です👶🏻 - 自作サービスで使おうかと思っているAPIのドキュメントが全部英語なので心が折れそうです - :tsurai: - https://musicbrainz.org/doc/MusicBrainz_API - hikaru - サッカー観て朝から盛り上がりました〜 - 久しぶりにわからなさすぎて凹んだ... - @garammasala29 - サッカー観てて寝不足でぼーっとしていました。無職の特権。 - :wakaru: - @haruguchi - 風邪引きました。気をつけてください。 - お大事に:cake: :tea: - JSで難しいと感じることは何ですか? - this - Promise - 非同期処理 - 関数の定義方法がいっぱいある - 式とは - LEF - 今流行りのChatGPTを試しに使ってみたら凄かったです🤖 - Windows(WSL2)で詰まりやすいところはLEFの日報とブログとQ&Aにたくさん書いたので、もしWindows使いたくなったら見てね! ----- ## 2022\-12\-5(月) haruguchiさんのバリデーションのPRモブプロ ### 自由に使う共有スペース ### 各自の疑問点や気づき、学んだこと - @haruguchi - すごい久しぶりにドライバーやった気分 - やっぱり手を動かさないと何にもわからぬことがわかった - `validates :column, foo: {message: 'hoge'}`のfooはおそらくvalidatorクラスのクラスネームから引っ張ってきてるっぽい→でした ```ruby! def validates(*attributes) defaults = attributes.extract_options!.dup validations = defaults.slice!(*_validates_default_keys) ←ここ! raise ArgumentError, "You need to supply at least one attribute" if attributes.empty? raise ArgumentError, "You need to supply at least one validation" if validations.empty? defaults[:attributes] = attributes validations.each do |key, options| ←ここ! key = "#{key.to_s.camelize}Validator" begin validator = key.include?("::") ? key.constantize : const_get(key) rescue NameError raise ArgumentError, "Unknown validator: '#{key}'" end next unless options validates_with(validator, defaults.merge(_parse_validates_options(options))) end end ``` - Saki - 実際にP.489の12.18を作ってみるとコードの流れがよく分かりました! haruguchiさんありがとうございました🙏 - `record.errors.add(attribute, options[:message] || 'うおおおおお')` - デバッグすると、`record`にエラーが発生したEventモデルのレコードが入っている - Eventモデルでバリデーションの設定を書く時に、`name: true`とか`name: {message: 'わいわい'}`と書くと、定義したnameバリデーターが発動する - `\\`は、左辺でtrueがかえってくる値がかえてこなければ、右辺に行く - `name: true`の場合、右辺の'うおおおおお'がエラーメッセージとして帰ってきて、`name: {message: 'わいわい'}`だと'わいわい'がエラーメッセージとして返ってくる - Eventモデルだけで無くTicketモデルとか他のモデルでも同じバリデーションを使いたい時、EachValidatorを使ってどのモデルでも使えるように切り出す - @garammasala29 - `ActiveModel::EachValidator`を継承したクラスで`validate_each`を使えば、エラーメッセージを上書きや追加ができる。 - 共通のバリデーションルールということで、今回の場合は違うフォームが出てきた時に同じバリデートが使えるという認識でよいのかな - そうだと思います!モデルごとに何回も同じバリデーション書くの防げます - @fuwa - 自作validationのエラーメッセージの流れがわかってよかったです〜うおおおおお - addメソッドの`:invalid`は今はつけないようにしましょう - @tomonari - 動かしてみるとvalidate_eachの引数がきちんとフォームに対応していてなるほどと思いました! - messageカラムでカスタムバリデーションのメッセージを変えられるというのは一度プラクティスのどこかでやったのですが忘れていたので確認できてよかったです。 - 最後のadd内のinvalidがシンボルなのはなぜなのでしょう? - シンボルだとto_procできたり、メソッドオブジェクトに変換したりできるからだと思います - :foo.to_proc.callでメソッド呼び出しとかできるので - hikaru - ActiveModel::EachValidatorの`validate_each`はフックになっているので、これをオーバーライドして使う - オブジェクト指向設計実践ガイドに出てきたな... :sousou!:設計の話ですね - `name: true`の部分は、本書の`validates メソッドの内部では、「#{ オプション名 .to_s.camelize}Validator」という名前のク ラスのインスタンスが、オプションに指定した値で初期化されます。`に対応している? - 👌 - dawa - 用意されてるバリデーションしか使ったことがなかったので、勉強になりました。 - maimu_x2x - 自作validationのエラーメッセージがどのような流れでフロントに出力されるかが分かりやすかったです! - or条件で左辺と右辺を判断してエラーメッセージが変わるという点は動かして見るとシンプルだけど、読んだだけではわからなくなりそうだなと思ったためロジックとして覚えておきたい ### 本日の振り返り(よかった点・次回に向けての改善点・今の気分などなんでもOK) - LEF(代読お願いします) - パRails輪読会楽しかったです! 半年間、ありがとうございました!🎉 - Sakiさん主催お疲れ様でした! 就活も頑張ってください、応援してます💪 - dawa - 最後だけの参加でしたが、みなさんお疲れさまでした。この分厚い本の輪読を毎日続けてやり終えるのは素晴らしいと思いました。haruguchi先生、ありがとうございました。sakiさん、就活頑張ってください。 - @fuwa - パRails輪読会楽しかったです〜!本当にありがとうございました!お疲れ様です! - Saki - みなさんご参加ありがとうございました!参加者の方々いないと輪読できないので本当に感謝です!就活がんばります - やっと昨日職務経歴書が一旦書き終わってtogoさんに添削お願いしたんですが12ページでした。12って多いですか??😅 - 私は転職する際2枚とかだった記憶です - 僕も2枚くらいでしたかね... - 情熱プログラマー - @haruguchi - パRailsの運営お疲れ様でした - 自分が参加する輪読会がついになくなった - パRailsの理解は7割くらいなのでまた何回も読み直したい - @garammasala29 - Sakiさん主催ありがとうございました。haruguchiさん説明ありがとうございました! - 輪読会のおかげで平日のリズムが作れていたので、本当にありがたかったです〜サミシイ:cry: - maimu_x2x - sakiさん、輪読会の主催お疲れ様でした!参加してみんなで考えながらRailsが学べてとても良い時間でした☺️ - 平日木金でJSPrimer輪読会をやるためお時間が許す方&興味がある方は気軽に参加いただけると嬉しいです〜! - 参加します〜 - gogo! - hikaru - パRails輪読会楽しかったです! Sakiさんありがとうございました〜 - Programming Ruby 3.2輪読会やるらしい :e----!: - これからも雑談してください! - @tomonari - パRails輪読会半年間お疲れ様でした!初めて参加した輪読会でしたが、おかげさまで毎日楽しく参加することができ、大変勉強にもなりました。