5
2

More than 1 year has passed since last update.

【Rails】find_or_create_by!を使ってみた

Last updated at Posted at 2021-02-13

概要

  • 参加させていただいている案件で、大変参考になった内容があったため、まとめました。

目的

  • rails db:seedで新しいテストデータを追加した時、差分だけ登録できるようにしたい

問題

  • rails db:seedで登録する時に、データが重複する部分でエラーが発生する
  • エラーが発生しないようにするには、その都度データをリセットする必要がある(rails db:migrate:resetなど)
  • 個人であれば問題ないが、複数人で作業している場合、「他のメンバーが追加したテストデータ」を「削除コマンドなし」で導入できるようにしておきたい

エラーが起こる原因

  • seeds.rbに登録されているデータが全て登録されようとする
  • 重複部分があるため、エラーが発生する

課題

  • データが存在しない場合は作成
  • データが存在する場合は、作成する処理を実行しないようにしたい

解決策

  • find_or_create_by!を使用する
モデル.find_or_create_by(条件)

#=>条件に一致するデータがない => 実行される(作成)
#=>条件に一致するデータがある => 実行されない(作成されない)

これで、データが存在する時、実行されることで発生するエラーは発生せず、差分だけ実行されます!

before

seeds.rb
User.create!(
  email: "test@example.com"
  password: "password"
)

rails db:seed   #=>1回目はデータがないため作成される
rails db:seed   #=>2回目はデータがあるためエラーが発生する

after

seeds.rb
User.find_or_create_by!(email: "test@example.com") do |user|
  user.email = "test@example.com"
  user.password = "password"
end

rails db:seed   #=>1回目はデータがないため作成される
rails db:seed   #=>2回目はデータがあるため、実行されない => エラーなし!

まとめ

他の人の動作まで考えてプログラムを組める人って素晴らしいですね。どんどん使って行きます!

参考資料

5
2
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
5
2