【第22週】パRails輪読会🚂 (2024-01-15~ 2024-01-19)

tags: パRails🚂

目次


2024-01-15(月)

ファシリ

@shodan

ドライバー

@hiromisugie

読んだところ

7-6-4 「バリデーションをテストする」から
8-1-2 「既存のフォームに画像アップロード機能を追加する」 383p まで。(途中です。)
PR: https://github.com/PerfectRubyonRails-Rindoku/Perfect_Ruby_on_Rails_Ch6/pull/24

次回

8-1-2 「既存のフォームに画像アップロード機能を追加する」 384p から。🚂

学んだこと・感想

  • @sharoa

    • 本にはバリデーションをテストする項目があったけど、実際のところはやらない?らしい。プラクティスのテストの時にまたここを思い出せたらな、と思います。
    • Eventモデルに画像を紐づけるための宣言を追加する(has_one_attached :image)これでEventモデルでimageと言う名前の属性が使えるようになる。
    • フォーム中に新しく追加した属性を受け入れてもらうためには、コントローラーのevent_paramsメソッド中のpermitメソッドに渡す引数に、追加した属性(今回だとimage``remove_image)を許可すべきリストとして追加しないといけない。
    • この何かを追加したから、ここにもそれを追加みたいな作業を忘れがちになりそうなので、気をつけたいと思う。
  • @shodan

    • バリデーションテストをする・しないについて、この本の説明が聞けてよかったと思います。
    • フォームで新しい属性を受け入れることにしたのに、受け入れ側のコントローラのストロングパラメータに追加し忘れるというよくある(?)間違いにハマれたのも、勉強という意味でとてもよかったな思います。
    • なんか明日のremove_imageまわりがややこしそう。。
  • @hiromisugie

    • テストは面倒だけど、コード全体のメンテナンスコストを下げてくれるので、ちゃんと書くのが大切(というのはめちゃくちゃよく聞くけど、実感したことがないので、早く実感してみたい)
    • ActiveStorageの設定
      • bin/rails active_storage:install
      • bin/rails db:migrate
      • 画像を持つモデルにhas_one_attached: image(複数画像の場合はhas_many_attached: images
      • ビュー・コントローラの設定(ストロングパラーメータの追加は忘れがちなので注意)
  • @ayu-0505

    • バリデーションテストについて、プラクティスのテスト技法では「必要性が薄い(もっと他にテストすべきとこあるやろ?)」的な感じでした。でもこの中で実際のやり方を見ることができて、「通常時は避けるが必要時には行う」やり方が分かってよかったです。
    • Active Storage周りをちょっと忘れかけているので要復習。
    • ストロングパラメーター追加忘れはプラクティスだか書籍だかでそのままやってしまってしばらくハマったような記憶。
    • 今回はActive StorageのDBはデフォルトだけど、こういったサーバーまわり?は自作サービス関係で結構な鬼門になりそうで今から恐ろしい。
  • @motohiro-mm

    • バリデーションのテスト方法もさらっと知れて良かったです
      • valid?:バリデーションが実行された結果エラーが無い場合trueを返し,エラーが発生した場合falseを返す
      • assert_empty:与えられたオブジェクトが空である場合、検査にパスしたことになる
    • ストロングパラメータに追加しないと許可されてないのでデータに保存されていない事が実際やってみて分かって良かったです
      • すぐ気づいたsuigeさんすごい!
    • ActiveStorageを以前やったはずなのにすっかり忘れていました…
      • フィヨブーフェスの時にpenoさんが「ぱRailsは辞書のように使ってる」っておっしゃってたのを思い出しました。ActiveStorageのところに戻って軽く目を通そうかなと思いました。
  • @moegi29

    • 今日でテストの章終わり。テストを書いてメンテナンスしていくことはそのコストを払っても得をする大きなメリットがあることになる。バグを見つける守備範囲が広い、メンテナンス容易なテストが良いテストという定義らしい。
    • プロジェクトによってはバリデーションテストをする場合もある。バリデーションをテストする場合、 簡潔に書くためのマッチャーを用意してくれるgemがある。
    • セキュリティの対策としてもストロングパラメータは自分がいれたもの以外は許可しない、今回は許可するのにimageとremove_imageを両方入れている

2024-01-16(火)

ファシリ

@motohiro-mm

ドライバー

@hiromisugie

読んだところ

8-1-2 「既存のフォームに画像アップロード機能を追加する」 384p から

PR:

次回

8-1-4 「容量が大きいファイルをアップロードした場合にバリデーションエラーにする」から。🚂

学んだこと・感想

  • @sharoa

    • remote_imageはEventモデルに対して独自に追加した属性だから、attr_accessorで明示的に属性を宣言する。
        - attr_accessor
    • dependent :falseを追加すると、イベントが削除された時に関連するActiveStorage::Attachmentのみが削除されるが、関連するActiveStorage::Blobと画像やサムネイルは手付かずの状態になる。(削除したい時は自由なタイミングでできる。)
    • サムネイルを生成するの節で、初めてアクセスしたタイミングでサムネイルが作成される。リサイズした画像は設定したストレージに保存されるので、2回目のアクセス以降はサムネイル生成はされない。
    • バリデーションエラーの設定をしたはずなのに、なぜかできちゃう現象、、、、明日で解決できるかな?
  • @moegi29

    • shodanさんがはってくれたリンクでActiveRecord::Type::Boolean.new.cast で文字列をBooleanに変換できることを知りました
    • イベントが削除されたときに関連するActiveStorage::Attachmentのみ削除、関連するActiveStorage::Blobと画像サムネイルは手つかずの状態になるので、自由なタイミングで削除できる。表示上の画像と関連付けが削除されるということ、Ayuさんが例に挙げてくれたはてなブログの例がわかりやすかったです。
    • 論理削除:実際にデータベースからは削除せず、本当は消えていないけれど、消えているのと同じ扱いにすること
    • ActiveStorageはファイルの中身から判断してアップロードしてくれる。テキストファイルにイメージ用の拡張子(今回はpng)をつけた場合は残念ながらはじかれない。w
  • @shodan

    • いくつかのパターンの文字列をブーリアン値に換えてくれるメソッドがある。
      • ActiveRecord::Type::Boolean.new.cast('true')
    • アップロードされたファイルの関連の定義で、dependant: falseオプションをつけると、関連元のオブジェクトが削除されたときに、その「関連」だけを削除するようにできる(元のファイルそのものや、それに紐づくテーブル上のレコードは削除されない)。
    • アップロードされた画像を編集して扱いたいときは、image_processinggemを導入する
    • アップロードされる画像のバリデーションをしたいときは、active_storage_validationsgemを導入する
      • 上記で通したいファイルのタイプ(:pngとか)を指定した時、ActiveStrageはファイル名ではなくファイルの中身が本当にpngかどうかを判断してバリデーションを行う
  • @motohiro-mm

  • @sadanora

    • ActiveRecord::Type::Boolean.new.cast
      • 引数に渡された文字列のtrue、falseなどをBool値に変換してくれるらしい
    • has_one_attched :image, dependent: false
      • 「イベントが削除された時に関連するActiveStorage::Attachmentのみが削除されます。」とあるけど、Railsガイドにdependent: falseについての説明が見つけられずちょっともやっています。
  • @ayu-0505

    • remove_imageattr_accessorで属性宣言し、before_saveコールバックでtrueかどうか判断し、trueならばimage属性をnilにする処理で画像保存を削除している。
    • ActiveRecord::Type::Boolean.new.cast('文字列')で文字列を真偽値変換できる
      • どのような文字列がtrue/falseになるのかは確認(大体の共通認識通り?)
    • vipsがRails7からは標準
    • Content TypeによるActive Storageの判断は絶対的に信頼して使うのはやめたほうがいいかも?
  • @hiromisugie

    • dependent: falseはイベントが削除されたときに関連だけが削除されるが、ActiveStorage::Blobと画像やサムネイルは削除されない
    • サムネイル生成の機能、Rails7からはImageMagickではなくvipsがデフォルトになっているらしい、shodanさんありがとうございます!
    • 該当ページに初めてアクセスしたときにサムネイルが生成されて2回目以降はそれが使われる、というのが何気に便利だなと思った
    • 特定の拡張子以外のファイルがアップされたときにバリデートをかけるのはvalidates :image, content_type: [:png, :jpg, :jpeg]のように書く。
      • 「テキストファイルの拡張子をpngにしてもActiveStorageは中身を見て判断してくれるからエラーになる」と書いてあったが、エラーにはならなかった…😂
      • 話は逸れるけど、Content Typeまで見なくても拡張子だけでバリデートしてくれれば別にいいけどと思ったが、実際には良からぬ操作をする人もいることを想定しなきゃいけないんだなと思った

2024-01-17(水)

ファシリ

@hiromisugie

ドライバー

@motohiro-mm

読んだところ

8-1-4 「容量が大きいファイルをアップロードした場合にバリデーションエラーにする」から
8-1-5 「縦幅や横幅が大きすぎる画像をアップロードした場合にバリデーションエラーにする」まで。
PR:https://github.com/PerfectRubyonRails-Rindoku/Perfect_Ruby_on_Rails_Ch6/pull/26

次回

8-1-6 「ダイレクトアップロード時にバリデーションをしたい時の注意点」から。🚂

学んだこと・感想

  • @sharoa

    • 容量の大きいファイルや、縦横幅の大きすぎる画像のアップロードした場合にバリデーションエラーを発生させるところで、昨日content_typeを追加したvalidatesに、sizeとdimensionも追加したら、昨日の謎(本当はエラーが出ないといけないのに作成できてしまう件)が解決してしまった。また謎ができたw
    • とりあえず、容量が大きかったり、サイズの幅が大きすぎる時のバリデーションエラーが本通りに確認できたことはよかった。
  • @moegi29

    • 縦幅や横幅が大きすぎる画像からサムネイルを作ろうとするとアプリケーションサーバのメモリやディスク容量を使い果たしてしまう
    • validatesにsize: { less_than_or_equal_to: 10.megabytes }, dimension: { width: { max: 2000 } , height: { max: 2000 } }というアップロード制限のコードを追記すると昨日の不具合が解決された
    • 今日はみんなで実験してる感じが楽しかったです
  • @sadanora

    • ActiveStorageValidationsを使うと縦横の幅や容量に制限をかけることができる。
    • 「pngの拡張子に偽装したテキストファイル」が昨日は通ってしまっていたのに、一見関係なさそうな今日のコードを追記したらバリデーションが効くようになったのなぜ
  • @hiromisugie

    • バリデーションの続き。
      • 容量が大きいファイルをアップできないようにする →size:で設定
      • 縦幅・横幅が大きすぎるファイルをアップできないようにする →dimension: で設定
    • 上記の設定をした結果昨日の不具合(テキストファイルにpngをつけたらアップできないことを期待したがアップできてしまった)が解消され、「???」となった…
    • 自分が作ったファイルに問題があるのかと思いヒヤヒヤしていたのですがそうではなかった。が、むしろ謎が深まってしまった…。
  • @motohiro-mm

    • validatesを複数書く書き方をあまりやったことがなかったので新鮮でした
    • 昨日通ってしまったcontent_typeのバリデーションが、容量やサイズを設定したらきちんとバリデートするようになっていた…なぜ?
    • git stashのやり方を全然わかっていないので調べようと思いました、sadanoraさんのメモも読みます、ありがとうございます〜
  • @ayu-0505

    • sizeのless_than_or_equal_toで大きい容量画像のバリデーション
    • dimensionのwidthheightで縦横の幅のバリデーション
    • バリデーションが中途半端に作用しなかったのはまだ謎…なんか内部の問題なのかな〜という印象

2024-01-19(金)

ファシリ

@moegi29

ドライバー

@sugiwe

読んだところ

8-1-6 「ダイレクトアップロード時にバリデーションをしたい時の注意点」から
8-2-2 「Searchkickでイベント検索機能を作る」の途中まで。
PR:https://github.com/PerfectRubyonRails-Rindoku/Perfect_Ruby_on_Rails_Ch6/pull/27

次回

8-2-2 「Searchkickでイベント検索機能を作る」のインストールするところから。395p。🚂

学んだこと・感想

  • @sharoa

    • ActiveStorageはダイレクトアップロードをサポートしている、と前置きしたあとで、ActiveStorageValidationsによるバリデーションには注意点がある、と書かれており、なんだかややこしいな、というのが印象です。
    • 自分的にダイレクトアップロードの仕組みがよくわかっていないので、あとでshodanさんが貼ってくれたURLと合わせて調べてみたいと思います。
    • ただ、相変わらずはじいて欲しいものがはじかれないという現象が直らなくて謎ですね。
    • kaminariのところはなんだか落ち着いて見ることができましたw
  • @motohiro-mm

    • ダイレクトアップロード:ブラウザからRailsアプリでデータを受け取ることなく直接クラウドストレージにアップロードできる
    • ダイレクトアップロードでは不完全なバリデーションしかできない(らしい)
    • kaminariはなんだか懐かしかったです
    • 検索機能は、検索対象のレコード数が少なければActiveRecordのクエリメソッドでできる
      • レコード数が多かったり、仕様が複雑なときは他の検索エンジンを使う(今回はElasticsearch)
  • @shodan

    • ダイレクトアップロードは、Railsのアプリケーションサーバを通さず、クライアント側からクラウドストレージに直接ファイルの実態を保存する方法
    • このとき、通常のバリデーションが同じように機能しないことがあることに注意
    • もしかしたらなんですが、Elasticsearchのバージョンが本の時から進んで、インストールするためのコマンドが変わったかも?
    • 最新のインストールガイドページ https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html
    • 一つ前のバージョンのインストールガイド https://www.elastic.co/guide/en/elasticsearch/reference/7.17/targz.html
    • ↑ここで本で紹介しているコマンドが載っていて、最新のコマンドは全然ちがいますね。
  • @sugiwe

    • ActiveStorageはちょっと鬼門かもと思った…!自作サービスやその先で画像アップロードを扱うことになったら気をつけたい。
    • kaminariはプラクティスの復習にもなってよかった!
    • kaminariの表示をいい感じにするbootstrap用のビューテンプレートが用意されていることを知った
    • 検索機能は結構ややこしくて、Elasticsearchなどの全文検索エンジンを利用すると実装しやすいらしい

Select a repo