LoginSignup
1
0

More than 1 year has passed since last update.

seed_fuのseedメソッドの引数を活用すれば、似たデータが重複して新規作成されることもないし、idをわざわざ書く必要もないぞと気づいた

Last updated at Posted at 2023-02-09

困ったこと

Railsのseed_fu、こういう風にidなどprimary keyを書くのを巷でよく見かけます。

db/fixtures/users.rb
User.seed do |s|
  s.id = 1 # ←
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

User.seed do |s|
  s.id = 2 # ←
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end

idなんて自動採番されるんだから、書く必要なくない?...ほら、削除してもデータ作れるじゃん!と無邪気にどや顔していたのですが、青二才でした。

確かにデータは作れます。しかしながら、seed_fuがいいのは、2回目以降流す時に、変更点だけを追加、または更新してくれるところ。primary keyを指定してあげないと、seed_fuは既存データか新規データかを判別できず、新しいデータをcreateしてしまいます。上記の例で言うと、鈴木一朗、鈴木二朗がダブってできてしまいます。

でもそうしたくない時があると思います。

とほほ。じゃあidを書いてあげて、インクリメントしていくしかないのかと諦めかけました。こんな感じで↓

db/fixtures/users.rb
id = 1

User.seed do |s|
  s.id = id
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

id += 1

User.seed do |s|
  s.id = id
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end

もっといい感じのやり方

ちゃんとドキュメントを読んだら、もっとスマートな方法のヒントが書いてありました。

seedメソッドの引数に「このカラム見てね、あったら新しく作らないでね」と教えておけば、そのカラムで同じデータがDBに既にある場合、それは既存のデータとみなしてくれます。User.seed(:name)という具合です。

db/fixtures/users.rb
User.seed(:name) do |s|
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

User.seed(:name) do |s|
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end

上の例では、DBのnameカラムの中で同じものがあればそれは既存のデータと見なされ、新しくcreateされることはありません。
複数のカラムでデータを特定したいときは、User.seed(:name, :email)と引数を複数指定してあげることもできます。

スマートで、ちょっとハッピー。

余談

本記事のタイトルの文字数が長いです。

seed_fuのseedメソッドの引数を活用すれば、似たデータが重複して新規作成されることもないし、idをわざわざ書く必要もないぞと気づいた

70文字です。
でもQiitaのタイトルは255文字まで行けるそうです。

1
0
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
1
0