3
3

【備忘録】モデルにバリデーションを追加後、seed実行時のエラー

Last updated at Posted at 2024-02-15

背景

モデルにバリデーションを追加後、rails db:seedを実行した時のエラーと解決策について備忘録がてら投稿します。

ユーザーからフォームの値を受け取った時、名前と画像を必須項目にしたかったため、Itemモデルに以下のバリデーションを追加しました。

item.rb
  validates :name, :image, presence: true

その後rails db:seedを実行すると...

ActiveRecord::RecordInvalid: バリデーションに失敗しました: 画像を入力してください (ActiveRecord::RecordInvalid)

今までは問題なく動作していたseed実行時にエラーが発生しました。

原因

原因はバリデーションが実行されるタイミングです。
エラーが起きた時のseedファイルのコードは以下です。(一部抜粋)

seed.rb
item = Item.create!(name: 'name')
item.image.attach(***)

この場合、item = Item.create!(name: 'name')の時点でバリデーションが実行され、:imageがアタッチされる前の段階のため「画像が入ってないよ」とバリデーションに引っかかってしまいます。

バリデーション実行のタイミングについてRailsガイドに記載がありました。
https://railsguides.jp/active_record_validations.html#バリデーション実行時の動作

以下のメソッドではバリデーションがトリガされ、オブジェクトが有効な場合にのみデータベースに保存されます。

  • create
  • create!
  • save
  • save!
  • update
  • update!

解決策

上記の6コマンドは実行時点でバリデーションも実行されるとのことです。これを踏まえ、以下のように修正しました。

seed.rb
item = Item.new(name: 'name')
item.image.attach(***)
item.save!

Item.createでインスタンス作成と保存を同時に行うのではなく、一旦Item.newで作成→画像をアタッチ→item.save!で保存するようにしました。
この変更によりsave!のタイミングでバリデーションが実行されます。item.image.attach(***)後に実行されるためバリデーションエラーを回避することができました。

学び

今回のエラーから二つ学ぶことができました。

  1. newcreateの違い
    • new: インスタンスを作成するだけ
    • create: インスタンス作成+保存
  2. バリデーション実行のタイミング

またネタができたら投稿します:)

参考

https://railsguides.jp/active_record_validations.html#バリデーション実行時の動作

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3