Rails3 to Rails4 変更点まとめ:1 / 4 »

カテゴリー:
Rails
タグ:
 Rails Rails4 変更点 Rails3

このエントリーをはてなブックマークに追加
更新日時:
2014年01月26日(日)
作成日時:
2013年08月01日(木)

前の記事 / 次の記事

Rails4にアップデートしてみた時に気付いたことなので、
Rails3の時から既にそうなっていたものもあるかも知れない。

で、その場合でもどの時点から変更されたのかは特に調べてないです。

積極的に変更点を調べたものではないのでアップデート過程で自分が遭遇
していない変更点については大きな変更点でもスルーしてる可能性があります。

また、StrongParameter、Turbolinks、RussianDollCachingについては
この記事とは別にまとめました。

StrongParameter、Turbolinks、RussianDollCachingについて

参考書

参考ページ(他サイトの同じテーマのページ)

目次

  1. default_scope はブロックが必須に
  2. rails s した時に実行していないMigrationがあるとエラーになる
  3. コントローラーの xxx_filter が xxx_action になった
  4. xxx_paramsというメソッドでStrongParameterが適用される(scaffoldで生成した場合)
  5. ストロングパラメーターは嵌まる
  6. ソシエーションの条件指定もブロックによる指定が必須に
  7. Model.noneメソッドが使える
  8. session の格納先は :cookie_store がデフォルトに
  9. 従来のキャッシュ機能は廃止されている
  10. form_tag ヘルパーの { remote: true } は data: { remote: true} として指定する
  11. orderにハッシュを渡せる

1.default_scope はブロックが必須に

default_scope where(active: true)

とか定義したら。

DEPRECATION WARNING: 
  Calling #default_scope without a block is deprecated.
  For example instead of `default_scope where(color: 'red')`, 
  please use `default_scope { where(color: 'red') }`.
  (Alternatively you can just redefine self.default_scope.). 

と言われた。ので、default_scope を定義する時は次のようにする。

 default_scope { where(active: true) }

名前付きスコープについ可変する値(時間とか)をセットしてバグっちゃう件の改善?

2.rails s した時に実行していないMigrationがあるとエラーになる

Rails3の時は、rails s した時に実行してないMigrationがあっても立ちあがったけど、
Rails4では、rails s した時に実行してないMigrationがあると 立ちあがらない

3.コントローラーの xxx_filter が xxx_action になった

before_filter とかが before_action になった。
xxx_filter も使える、非推奨にはなってない模様。

4.scaffoldで生成されるコントローラーにプライベートメソッドset_xxxが生成される。

例えば

class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update, :destroy]

  private
    def set_book
      @book = Book.find(params[:id])
    end
end

みたいになる。

これによって show, editアクションのコードが0行になっている。

4.xxx_paramsというメソッドでStrongParameterが適用される(scaffoldで生成した場合)

scaffolでコントローラーを生成した場合、
例えば次のようになっていて、paramsを使うような感覚で自然にStrongParameterを適用できる。

class BooksController < ApplicationController
  def create
    @book = Book.new(book_params)
   ~~
  end

  private

    def book_param
      params.require(:book).permit(:author_id, :title)
    end

end

5.ストロングパラメーターは嵌まる

ストロングパラメータが当たり前になれば嵌まることもなくなるんだろうけど、
ある値が反映されない時に、ストロングパラメーターの存在を忘却していて嵌まる。

コントローラーで新規作成や更新をかけて思ったように反映されなかったら
真っ先にストロングパラメーターの定義が間違っていることを疑うべし。

ストロングパラメーターで定義していない値を受け取ったらエラーにすることもできる。
エラーをraiseさせる方法は次のページを参照。
Rails4のStrong Parametersの使い方まとめ

6.アソシエーションの条件指定もブロックによる指定が必須に

次のようなコードは非推奨となり

has_many :daughters, class_name: Child, conditions { gemder: "female" }

条件指定はブロックによることが望ましい

has_many :daughters, -> { where(gemder: "female") }, class_name: Child

ちなみに、ブロックを指定する場合、それは必ず最初のパラメーターでなければならない。
例えば次のコードはエラーになる。

has_many :daughters, class_name: Child, -> { where(gemder: "female") }

色んなサイトにRails4ではラムダ式が必須に的なことが書いてあるんだけど、
ここで指定するブロックはラムダ式の方が望ましいのかブロックなら何でもいいのか不明。
ていうか lambda と proc の違いが相変わらずよく分からん。

7.Model.noneメソッドが使える

Model.none で空の ActiveRecord::Relation を得られる。

例えば

persons =
  case true
    when age >= 10 && age < 20 
      Person.where generation: "teen"
    when age >= 20 && age < 60
      Person.where generation: "adult"
    else
      []
    end

みたいな処理があった時、

persons =
  case true
    when age >= 10 && age < 20 
      Person.where generation: "teen"
    when age >= 20 && age < 60
      Person.where generation: "adult"
    else
      Person.none
    end

と書ける。

何が嬉しいのかと言うと、Person.none は配列ではなくて、空のActiveRecord::Relationなので、
例えば、次のように配列にはないメソッドを実行しようとしてもエラーにならないので嬉しい。

-# haml
%dl
  - persons.find_each do |person|
    %dt=pserons.name
    %dd=person.introduction    

# [].find_each はエラーになる

8.session の格納先は :cookie_store がデフォルトに

:cookie_sotre がデフォルトになったというより、そもそも :cookie_store しか使えない。
DBを session の格納先として利用したい場合は、別途 gem をインストールしていくつかの設定をする必要がある。

以下、DBを session の格納先として利用する場合の手順。

8.1.gem をインストール

$ vi Gemfile

gem 'activerecord-session_store'

$ bundle install

8.2.session の格納先に :active_record_store を指定する

$ vi config/initializers/session_store.rb
Stollees::Application.config.session_store :active_record_store, key: '_appname_session'

8.3.session を格納するテーブルの migration を生成する

従来の rake db:sessions:create では作成できない ので注意

$ rails g active_record:session_migration

8.4.session を格納するテーブルを作成

$ rake db:migrate

以上。

参考

[Rails]RailsでセッションデータをDBに保存する情熱。
stakoverflow: rails 4.0, rake db:sessions:create

9.従来のキャッシュ機能は廃止されている

RussianDollCachingが導入されたのは知っていたけれど、
それだけではなく、そもそも今まであったキャッシュ機能というのは廃止されている。

caches_page , caches_action は使えない。

フラグメントキャッシュのようなものは引き続き利用できて、
それがつまりRussianDollCachingである。

従来のキャッシュ機能を利用したい場合は別途Gemを追加することで
引き続き利用することは可能。

Russian Doll Cachingについては別途次のページにまとめた。
Rils4で Russian Doll Caching を楽しむためのまとめ

10.form_tag ヘルパーの { remote: true } は data: { remote: true} として指定する

そもそもRails3の後半からだった可能性濃厚だし、
form_tagヘルパーに限ったことじゃないのだけど、

リンクやボタンをAjax化する時は、従来のように

=form_tag path, remote: true

とするのではなくて、

=form_tag path, data: { remote: true }

と指定する必要がある。

但し従来と同じように書いても、
JavaScriptが有効になっている場合は正常に機能するので注意。

従来の記法のままだとJavaScriptが無効にされている時に、
AuthenticityTokenが生成されずにActionController::InvalidAuthenticityTokenが発生する。

また、これは form_tag ヘルパーでの話で、
link_to ヘルパーに対しては従来と同じように単に remote: true を指定する。

何かの勘違いだったっぽい

11.orderにハッシュを渡せる

参考:Rails4からActiveRecordのorderにハッシュを渡せるようなった。

地味に嬉しい。

@objects.order("created_at desc")

じゃなくて

@objects.order(created_at: :desc)

と書ける。
従来の書き方でも書ける。