LoginSignup
24
24

More than 5 years have passed since last update.

Rails 4.0 find_or_create_by

Posted at

rails/activerecord/CHANGELOG.md @ 300d080ada31ac297264e6abba6ca16cd2db5925

を読んでみたので誤訳 & わからない部分は後で調べ直すためのメモ。

find_or_create_by, find_or_create_by!, find_or_initializeが追加されている。
これらのメソッドはfirst_or_create系のメソッドと似ているが、レコードが作られるときの振る舞いは少し異なっている。

User.Where(firstname: 'Hoge').first_or_create

はスコープのコンテキストで実行されるcreateコールバックを伴って

User.Where(firstname: 'Hoge').create

を実行する。これは、コールバック内で実行するクエリに影響を及ぼす。
(Whereの結果がcreateに影響するということでいいのかな?)

User.find_or_create(firstname: 'Hoge')

User.create(firstname: 'Hoge')

を実行する。これは明らかにコールバック内のクエリのスコープに影響を与えない。(うーん、確かにWhereが消えたのでWhereの結果がcreateのクエリを汚すことはないか。ただ、これだと、find_or_create_byのfindの意味合いがよくわからないとおもうのだが・・・。あとで調べ直す。)

find_or_create_byを利用したほうは読みやすく、素直だ。

もし、レコード生成時に追加で必要な属性があるなら、以下の方法のうちどちらかを採用すればいい。

User.create_with(active:true).find_or_create_by(firstname: 'Hoge')
User.find_or_create(firstname: 'Hoge'){|u| u.active = true}

first_or_create系のメソッドはfind_or_createのAPIを支持して、nodoc'edとした。first_or_create系のメソッドはそのうちdeprecatedとなるかもしれないが、これらの実装は少なく、たくさんのうっとうしいdeprecation warningをユーザに出す価値は多分ないでしょう。
("これらの実装は小さく"の部分がわからんなぁ。後で調べ直す。)

24
24
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
24
24