Rails4では、ActiveRecord周りの書き方に何点か変更が入っています。
普通にWebアプリを作る際には、もっともわかりやすい変更点の1つですね。
ActiveRecord::Modelのinclude
従来、モデルを定義するには
class User < ActiveRecord::Base end
としていました。
Rails4では、
class User include ActiveRecord::Model end
という書き方ができます。別クラスを継承させることができるのが大きなメリットです。
影響範囲が広く(ActiveRecord::Baseを拡張するライブラリが多いため)、ひょっとしたら4.1などで更に方針が変わる可能性もありますが、ActiveRecord::Baseに依存した書き方をしないように気をつける必要があります。
find_by_*の廃止
find_by_emailやfind_all_by_name_and_stateのような動的メソッドが、非推奨になりました。
複数取得(find_all_by_*)は、whereを利用します。
1件取得(find_by_*)は、新規に追加されたfind_byメソッドを利用するのが便利です。
User.find_all_by_email('test@example.com') ↓ User.where(email: 'test@example.com').all User.find_by_email('test@example.com') ↓ User.find_by(email: 'test@example.com') # !を付けると、findと同じく、見つからない場合に例外を発生する User.find_by!(email: 'test@example.com')
個人的には、find_by!の追加が非常に嬉しいです。これで、ID以外で1件取得するコードがすっきりします。
しかし、find_by_*はRails初期にかなり特徴として押し出され、他のフレームワークにも影響を与えた機能だけに、少し感慨深いですね。
scopeでlambdaが必須
3.2.7で一瞬導入された変更です。
scopeを書く際、うっかりTime.nowなどを書く人が多かったため、lambdaを使わないと警告がでるようになりました。
これは副作用なくRails3でも使えるので、今から積極的になれておきましょう。
# 非推奨 scope :red, where(color: 'red') default_scope where(color: 'red') scope :recent, where(published_at: Time.now - 2.weeks) # これはバグる # 推奨 scope :red, -> { where(color: 'red') } default_scope { where(color: 'red') } scope :recent, -> { where(published_at: Time.now - 2.weeks) }
scopedがdeprecatedになり、allがActiveRecord::Relationを返すように
従来、User.allはArrayを返していました。これが、ActiveRecord::Relationを返すようになります。
従来のscopedが新しいallになり、従来のallはall.to_aで代用します。scopedは非推奨になりました。
地味に注意が必要な点です。
その他
その他、SchemaCacheが導入されたり、リレーション周りの指定方法が若干変わっていたりと、色々変更されています。