Help us understand the problem. What is going on with this article?

Rails 4で非推奨になった/なっていないfinderメソッドを整理する

More than 5 years have passed since last update.

はじめに: 問題

さて、いきなり問題です。
Rails 4.0から非推奨(deprecated)になったfinderメソッドは次のうちどれでしょうか?

User.find_by_email('foo@example.com')

User.find_by_email_and_name('foo@example.com', 'Foo Bar')

User.find_by(email: 'foo@example.com')

User.find_or_initialize_by_email('foo@example.com')
# または 
User.find_or_create_by_email('foo@example.com')

User.find_or_initialize_by(email: 'foo@example.com')
# または 
User.find_or_create_by(email: 'foo@example.com')

答え合わせ

みなさん、わかりましたか?
正解はこちらでした!

User.find_or_initialize_by_email('foo@example.com')
# または 
User.find_or_create_by_email('foo@example.com')

それ以外のfinderメソッドはRails 4.0でも使えます。
というか、厳密にいうと以下のfinderメソッドはRails 4.0から新しく登場したfinderメソッドです。

User.find_by(email: 'foo@example.com')

User.find_or_initialize_by(email: 'foo@example.com')
# または 
User.find_or_create_by(email: 'foo@example.com')

なので、「Rails 3時代から引き続き使えるfinderメソッド」という意味では、該当するのは以下のfinderメソッドだけになります。

User.find_by_email('foo@example.com')

User.find_by_email_and_name('foo@example.com', 'Foo Bar')

非推奨になった/なっていないfinderメソッドを整理する

ここで上記の内容を整理してみましょう。

Rails 4.0からは非推奨になったfinderメソッド

User.find_or_initialize_by_email('foo@example.com')
# または 
User.find_or_create_by_email('foo@example.com')

Rails 4.0でも引き続き使えるfinderメソッド

User.find_by_email('foo@example.com')

User.find_by_email_and_name('foo@example.com', 'Foo Bar')

Rails 4.0から新しく登場したfinderメソッド

User.find_by(email: 'foo@example.com')

User.find_or_initialize_by(email: 'foo@example.com')
# または 
User.find_or_create_by(email: 'foo@example.com')

非推奨になったその他のfinderメソッド

Rails 4.0以降では User.find_or_initialize_by_... 以外にも非推奨になった以下のfinderメソッドがあります。

  • find_all_by_...
  • find_last_by_...

非推奨になったfinderメソッドを書き直す方法

非推奨となったfinderメソッドはそれぞれ以下のように書き直します。

# Rails 3
User.find_or_initialize_by_email('foo@example.com')
# Rails 4 (find_or_create_by_...の場合も同様)
User.find_or_initialize_by(email: 'foo@example.com')
# または
User.where(email: 'foo@example.com').find_or_initialize 

# Rails 3
User.find_all_by_name('Foo Bar')
# Rails 4
User.where(name: 'Foo Bar')

# Rails 3
User.find_last_by_name('Foo Bar')
# Rails 4
User.where(name: 'Foo Bar').last

書き直す時間がない!という場合は以下のgemを使って延命処置を施すこともできます。

Rails 4.1以降では警告ではなく、エラーになります

Rails 4.0で非推奨になったfinderメソッドはRails 4.1から使えなくなっています。
エラーが出た場合は新しい記法に書き直すか、activerecord-deprecated_finders gemをbundleしてください。

まとめ

find_by みたいなメソッド名を見るとつい「あれ、これって非推奨じゃなかったっけ?」と記憶があやふやになることが多いので、ここで一通り情報を整理してみました。

僕と同じように「あー、どれだっけ?」と迷った場合はこの記事を参考にしてみてください。

参考文献

jnchito
SIer、社内SEを経て、ソニックガーデンに合流したプログラマ。 「プロを目指す人のためのRuby入門」の著者。 http://gihyo.jp/book/2017/978-4-7741-9397-7 および「Everyday Rails - RSpecによるRailsテスト入門」の翻訳者。 https://leanpub.com/everydayrailsrspec-jp
https://blog.jnito.com/
sonicgarden
「お客様に無駄遣いをさせない受託開発」と「習慣を変えるソフトウェアのサービス」に取り組んでいるソフトウェア企業
http://www.sonicgarden.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away