tawara's blog

雑記。個人の見解です。

Userにbelong to で紐づくデータをseed_fuで作るときにeach_with_indexが活躍した

こんにちは、たわらです。

今回は業務で学んだお話です。

背景

User に belong to で紐づくseed データを作成する必要がありました。 たとえばこんな感じ。業務コードをだいぶぼかしているので変な感じするかもですが目をつむってください。

UserNickname.seed do |s|
  s.id = 1
  s.user_id = User.find_by(email: "user_001@bt.com")
  s.nickname = "hogetarou"
end

で、50人いるuserのseedデータすべてにnicknameをーー同じでもーー付与しなければならない。

愚かな対処

ボクはなにも考えずに50人分全員ベタ打ちで対処した。長い時間をかけて、こんなのエンジニアらしくないと頭では思いながら、、、

UserNickname.seed do |s|
  s.id = 1
  s.user = User.find_by(email: "user_001@bt.com")
  s.nickname = "hogetarou"
end

UserNickname.seed do |s|
  s.id = 2
  s.user = User.find_by(email: "user_002@bt.com")
  s.nickname = "hogetarou"
end

.
.
.

UserNickname.seed do |s|
  s.id = 50
  s.user = User.find_by(email: "user_050@bt.com")
  s.nickname = "hogetarou"
end

先輩のご指摘

PRレビューをすると「User.allをeachで回して作成する方が良さそう」とコメントされる。

なんと、その手があったか!

で、こんなふうに書いた。300行くらいあったコードがわずか10行程度になりました。すごい。

seed_id = 1
User.all.each do |user|
  UserNickname.seed do |s|
    s.id = seed_id
    s.user_id = user.id
    s.nickname = "hogetarou"
  end
  seed_id += 1
end 

each_with_indexの登場

Rubyっぽくないコードになっちゃってるね。each_with_indexを使うといいよ」と先輩がPRに再度コメントした。細かいところまで見てもらえてうれしい。seed_id += 1 のところらへんがRubyならもっとうまく書けるとのこと。

なるほど、each_with_index (!) どこかで読んだことあるメソッドだった。先輩に聞きながら実装すると、こんなふうになった。

User.all.each_with_index do |user, i|
  UserOrigin.seed do |s|
    s.id = i + 1
    s.user_id = user.id
    s.nickname = "hogetarou"
  end
end 

要素とそのインデックスをブロックに渡して、インデックスをブロック内で使えるのですね。 ちなみにインデックスは0からはじまるので、idなど1から開始したい場合はi + 1とします。

ひとこと

ベタ打ちで時間をかけて書いたコードがとてもすっきりとしました。時間を無駄にしてしまいましたが、「そういう経験も意外と大事だよ」と先輩は言います。たしかに長いコードを短くできた快感がありました。いい経験ができました。

参考文献 docs.ruby-lang.org