書店に行ったらまだ未発売の パーフェクト Ruby on Rails が並んでいたので購入してみました。これから読んで行きます。楽しみ。
さて本題
Rails4絡みの記事 をいくつか書いてますが、いろいろ知らなかったことがあったので、個人的にはとても良かったです。Release Notes に記載がないものや、より詳細な内容や注意点と合わせてコードが掲載されていて
これからRails4 やりますみたいな人はさらっと見てみるとよいかもしれません。
内容としては以下のような者が掲載されています。
・Rails4へのupgrade方法
・depricationsや削除された機能
・gem化された機能の紹介
・追加された機能
・Upgrad時のエラーと対応のまとめ
以下気になったところをメモ。
ActiveRecord
Relation#order (p.29)
orderのchain時に発行されるORDER BYの順序が変わります。これは注意が必要。
Comment.order("replies_count DESC").order(:created_at) -- Rails3 SELECt * FROM comments ORDER BY replies_count DESC, created_at -- Rails4 SELECt * FROM comments ORDER BY created_at, replies_count DESC -- Rails3/4 Comment.order("replies_count DESC", :create_at)
validates_format_of with ^ and $ (P31)
# app/models/post.rb class Post < ActiveRecord::Base # only alphanumeric chars and the hypen allowed validates_format_of :slug, with: /^A[A-Za-z0-9-]+$/ end
rubyの正規表現の話ですがsecurity risk軽減のために厳しくなったようです。
行の開始終了判定に^',
$'を使うとArgumentErrorになります。
^',
$'を利用すると改行を含めてチェックするため改行以降に
悪意のあるコードを突っ込まれる可能性があるためこれを回避するように
\A',
\z'を推奨するようになっています。
改行込みのときは、:multiline => true を設定することで対応可能。
ですので、基本的には書き換えが必要と。
(まぁ、メッセージ見りゃ分かるんですが)
安全側に倒すようになっていますね。
validates_confirmation_of (P.32)
パスワード確認用項目ですが、エラーのattribute名(とデフォルトのエラーメッセージ)が変更されています。 password -> password_confirmation
# Rails3 > user.valid? false > user.errors[:password] ["doesn't match confirmation"] # Rails4 > user.valid? false > user.errors[:password_confirmation] ["doesn't match Password"]
ですので、通常エラーメッセージ変更していると思いますので、ここも変更が必要です。
JSON Serialization (p.33)
to_json時の挙動が変更されています。
デフォルト config.active_support.escape_html_entities_in_json = true
がセットされるようになったため、htmlを含む場合escapeされます。
ActionController and ActionView
Strong Parameter (P.39)
機能については省略しますが、attr_accessible が無くなっています。strong parameter使えよってことのようです。一応、protexted_attributes gem が用意されています。
Caching
page / action cacheingは無くなりました。一応以下のgemが用意されています。
actionpack-action_caching gem
actionpack-page_caching gem
russian doll caching については Cache Digests にて後述。
ActiveSupport
Object#try (P.46)
receiverがnilでない場合の挙動が変更されています。
# Rails3 >> nil.try(:name) => nil >> "abc".try(:name) NoMethodError: undefined method `name' for "abc":String
# Rails4 # これは一緒 >> nil.try(:name) => nil # nilが返る >> "abc".try(:name) => nil # rails3と同じ挙動にしたい場合 try! >> "abc".try!(:name) NoMethodError: undefined method `name' for "abc":String
Thread Safety
defaultでthread safeが有効になっているようです。
(Rainbows!やpumaなどthread safeに対応したwebサーバが必要です。)
config.threadsafe! and config.eager_load (P.48)
Rails3にあったconfig.threadsafe!がなくなり、以下のoptinoが設定されています。
config.cache_classes = true
config.eager_load = true
eager_load をfalseにすると必要になったときに読み込まれるようで
development/test はfalseになっています。しかし、thread safeでどうささせるためにはこれが有効とのこと。
ActionController and ActionView (P.62)
ActionController::live
ActionController::Live を試す - rochefort's blog
Cache Digests (P.65)
fragment cacheの利用時にキー(以下の例ではv1)を設定し、変更が発生したタイミングでキーを変更する必要がありました。Rails4では、このキーを自動で設定してくれるという機能です。便利!!(というかこれまでが使いにくかった)
# Rails3 <%# app/views/whishlists/show.html.erb %> <%- cache ["v1", @wishlist] do %> <h1><%= @wishlist.title %></h1> <ul> <%= render @wishilist.items %> </ul> <%- end %> <%# app/views/sishlists/_item.html.erb %> <%- cache ["v1", @item] %> <li><%= @item.name %>(<%= @item.price %>)</li> <%- end %>
Russian Doll Cashingについてですが、外側のkeyが変更されると自動で内側のkeyも変更されていましたが、その逆の場合、つまり内側のkeyが変更された場合、外側のkeyが変更されませんでした。
Rails4では、以下のように記載すればokです。
# Rails4 <%# app/views/whishlists/show.html.erb %> <%- cache @wishlist do %> <h1><%= @wishlist.title %></h1> <ul> <%= render @wishilist.items %> </ul> <%- end %> <%# app/views/sishlists/_item.html.erb %> <%- cache @item %> <li><%= @item.name %>(<%= @item.price %>)</li> <%- end %>
See Also
・ActionController::Live を試す
・Rails 4.1 の新機能 - rochefort's blog
・Ruby on Rails 4.1 Release Notes #1(Rails4.1へのupgrade方法)
・"rails4" - 記事一覧