Rails 2.1の主な変更点を整理
以下のページを参考にRails2.1の変更点の概要を雑感を交えつつ整理してみた。
Riding Rails: Rails 2.1: Time zones, dirty, caching, gem dependencies, caching, etc
- タイムゾーンサポート – Time zones
- ActiveRecordによる変更のトラッキング – Dirty tracking
- 依存するgemを簡単に準備 – Gem Dependencies
- 検索条件ごとのファインダメソッドを簡単に作成 – Named scope
- グループ開発におけるマイグレーションの機能強化 – UTC-based migrations
- キャッシュ機構の強化 – Better caching
- その他
タイムゾーンサポート – Time zones
ユーザーのタイムゾーンにあわせた時刻表示が簡単になる仕組み。
これは本体に入れるほどの機能なの?とか思ってしまうのは島国根性というやつでしょうか。
・・・そういやアメリカとか普通にマルチタイムゾーンなのか。
動きは以下のようなかんじ。
Time.zone = 'Tokyo'
Time.zone.now #=> Sun, 01 Jun 2008 22:26:32 JST +09:00
Time.zone = 'UTC'
Time.zone.now #=> Sun, 01 Jun 2008 13:26:45 UTC +00:00
この時Time.nowの挙動はどうなるんだろうかと見てみると
Time.now #=> Sun Jun 01 22:26:48 +0900 2008
これは変わらないので、使わない人はスルーしてもよさげ。
と言いつつTime.zone.nowを使うプラグインなんかが出てきたらそうも言ってられないかもしれないが。
デフォルトのタイムゾーンはconfig/environment.rbで設定する。設定しないとnil。
2.1でアプリを作るとUTCが設定されているので、一応Tokyoとかにしておいた方がよいだろう。OsakaとかSapporoでもよい。
参考
ActiveRecordによる変更のトラッキング – Dirty tracking
ActiveRecordオブジェクトが変更されているか、どの値が変更されているか、変更前の値は何か、などの確認ができるようになった。
また、saveしたときには変更されている値のみがSQLに含まれるようになり無駄が少なくなった。(Partial Updates)
ActiveRecordのオブジェクトで以下のようなメソッドが使えるようになっている。
changed? | オブジェクトが変更されているかどうか確認する。変更されていたらtrueが返る。 |
changed | 変更されている属性名を配列で返す。 |
changes | 変更されている属性の名前と値をハッシュで返す。値は変更前と変更後の値の配列。 |
<attr>_changed? | 属性が変更されているかどうか確認する。変更されていたらtrueが返る。 |
<attr>_was | 属性の変更前の値を返す。変更されていない場合は現在の値(つまり同じ値)が返る。 |
<attr>_change | 属性の変更前と変更後の値を配列で返す。変更されていない場合はnilが返る。 |
<attr>_will_change! | 属性を変更することを明示する。代入以外で値を変更するときに使う。 |
上記のメソッドを使う場面がなくてもActiveRecoredが変更された値を管理していて、変更された値のみをSQLに含めるPartial Updatesが有効になっている。
そのため特に意識しなくてもRails 2.1にするだけで自然と更新の負荷が低減するという恩恵がある。
なおPartial Updatesはデフォルトで有効になっており以前のEdge Railsで必要だった以下の設定は不要になっている。
ActiveRecord::Base.partial_updates = true
参考
- [Edge Rails] ARオブジェクトの状態を知る: Dirty Objects | poqu.log
- [Edge Rails] 部分的なアップデート: Partial Updates | poqu.log
- Ryan’s Scraps: What’s New in Edge Rails: Dirty Objects
- Ryan’s Scraps: What’s New in Edge Rails: Partial Updates
依存するgemを簡単に準備 – Gem Dependencies
アプリケーションに必要なgemを明示することで他の環境での動作を簡単にする機能。
他の環境でのgemのインストールをサポートするほか、vender以下にもれなくgemを取り込むことができる。
これはいい機能だ。
まず利用したいgemをconfig/environment.rbに書く。
ここでは割愛するけれどもバージョンを固定したりといったこともできる。
Rails::Initializer.run do |config|
...
config.gem 'rmagick'
config.gem 'gruff'
config.gem 'hpricot'
...
end
そして依存するgemをシステムにインストールするには
$ sudo rake gems:install
これでconfig/environment.rbに書いておいたgemがすべてインストールされる。素敵だ。
gemをvender以下に取り込むには以下のようにする。
$ rake gems:unpack
参考
- [Edge Rails] Gemの管理を行う: Gem Dependencies | poqu.log
- Ryan’s Scraps: What’s New in Edge Rails: Gem Dependencies
検索条件ごとのファインダメソッドを簡単に作成 – Named scope
これは以前紹介したhas_finderの機能を本体にマージしたもの。
モデルのfindメソッドに与えるconditionsやorderなどの条件ごとにそれぞれをメソッドとして定義して便利に使うことができる。
Railsで開発してるとついコントローラに同じ引数のfindメソッドの呼び出しとか増えがちだけど、そういうものを自然とモデルの方にまとめたくなるよい仕組みだ。
簡単なサンプルコード。
モデルで定義して
class Item < ActiveRecord::Base
named_scope :stocked, :conditions => ["stock > 0"]
named_scope :has_image, :conditions => {:has_image => true}
end
以下のように使う。
items = Item.stocked.has_image
Named scope同士を連結して使うことができるというのがとてもいい。
さらにNamed scopeの後にfindや集計関数をくっつけることもできたり。
参考
- Edge Rails の named_scope がすごいみたい | poqu.log
- Ryan’s Scraps: What’s New in Edge Rails: Has Finder Functionality
グループ開発におけるマイグレーションの機能強化 – UTC-based migrations
マイグレーションは主に複数人開発に関する機能強化が図られている。
まずマイグレーションのバージョン番号がUTCのタイムスタンプベースのYYYYMMDDHHMMSSになった。
これにより複数人でRails開発すると必ず発生するバージョン番号のバッティングの問題が解消された。
またバージョン番号だけでなくバージョンの管理の仕方も若干変わって、管理テーブルの名前がschema_infoからschema_migrationsに変わった。
schema_infoの頃は最終のバージョン番号だけを記録していたが、schema_migrationsは適用したすべてのマイグレーションのバージョン番号を記録するようになった。
これはコミットのタイミングの違いなどで適用されないマイグレーションが出てくるのを防ぐための仕組み。
タイムスタンプのバージョン番号だけに頼ると、例えば1日前に作られてその日にコミットされたマイグレーションがある場合に、5日前に作られて今日コミットされたマイグレーションが適用されなくなってしまう。
schema_migrationsの管理方法にしたことで適用されていないマイグレーションを確実に見つけて実行できるようになったというわけだ。
ちなみに既存の2.0以前のアプリを2.1にした後でマイグレーションを行うとschema_infoからschema_migraionsへの変換は自動的に行われる。
デメリットとしてはバージョン番号が長たらしくなってエディタで開くときめんどうとかそんなかんじ。
正直ソロ開発者にとってはデメリットだけであんまりうれしくないですな。
ほか、rakeのマイグレーション関連のタスクが増えてて、各マイグレーションのupとdownを任意に実行できるようになってたりする。
参考
- [Edge Rails] Migrationの新しい採番方法:UTC-based Migration Versioning | poqu.log
- Ryan’s Scraps: What’s New in Edge Rails: UTC-based Migration Versioning
キャッシュ機構の強化 – Better caching
フラグメントキャッシュなどのキャッシュは今まではファイルに保存するしかなかったけれども、これをメモリやmemcacheやdrbなど他のキャッシュストアにも保存できるようになった。
定義はconfig/environment.rbなどで以下のように
ActionController::Base.cache_store = :memory_store
ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
ActionController::Base.cache_store = :mem_cache_store, "localhost"
何も指定しないときのデフォルトは:memory_storeになる。
このほかにも自作のキャッシュストアを作成して使うこともできる。
参考
その他
DBコンソールやhas_one :throughといったフィーチャーが有効になっているようだ。
“Rails 2.1の主な変更点を整理” に対して3件のコメントがあります。
コメントは受け付けていません。
フラグメントキャッシュをmemcached等で扱うってのはRails 2.0でもできてましたよ。
こんなかんじに。
memcache_options = {
:compression: false
:debug: false
:namespace: “Sample-#{ RAILS_ENV }”
:readonly: false
:urlencode: false
}
memcache_servers = [127.0.0.1:11211]
config.action_controller.fragment_cache_store = :mem_cache_store, memcache_servers, memcache_options
なるほど。
キャッシュストアを簡単に作る仕組みができて切り替えられるようになりました、というところが変更点の主眼ですかね。