Rails勉強会@東京第30回に参加してきた#2

さて続きを.と言うか,松田さんのPPで十分な気がしますが,とりあえずログを.

Rails 2.1の新機能

一番の目玉は named_scope ですね.これはかなり便利だ.

イントロ
  • Rails関係の情報源の紹介
  • has_one :through
    • 今までできなかったのか.あんまり使うことないような気もしますが,なきゃないで困るか.
  • named_scope
    • 後でも書きますが,SQLの合成がかなり良いな.
Rails 2.1を使ってみよう
  • インストール
    • 方法としては,
      • freeze
      • piston (git に対応したら)
      • git clone
    • 今回は git clone する.
$ rails edge-git
$ cd edge-git/vender/
$ git clone git://github.com/rails/rails.git
$ ls
  • rake tasks
  • script/dbconsole
    • database.ymlを見なくても,指定された environment の Database に接続してくれる.勝手に接続してくれるのは便利だな.いちいち「あれ?MySQLだっけ?」とか考えなくてもいいのは(ただ,それは忘れないだろうから,Username/Passwordの省入力化かな).
  • Model.create に block が渡せる
    • Rubyっぽいくていいらしいが,ちょっと使いどころが見えない....
  • Model.all / Model.first / Model.last が使える
    • それぞれ,Model.find(:all) / Model.find(:first) / Model.find(:all).last に対応.
      • これは後の named_scope に関連
  • dirty object
    • 変更された column がわかる.
      • model.column_changed? => true or false
    • 変更前の値もとれる
      • model.column_was
    • 前後の差異も見れる
      • model.column_change => [before, after]
>> p = Person.first
=> #<Person id: 1, name: "name", age: 20, gender: 1, created_at: "2008-05-19 22:19:31", updated_at: "2008-05-19 22:19:31">
>> p.name = "new name"
=> "new name"
>> p.name_changed?
=> true
>> p.name_was
=> "name"
>> p.name_change
=> ["name", "new name"]
  • named_scope
    • Model.all などのベースになっている
    • has_finder plugin が取り込まれた
    • :conditions などに名前をつけて method 化できる
    • method_chain で :conditons が追加されていく
class Person < ActiveRecord::Base
  named_scope :male, :conditions => {:gender => 1}
  named_scope :adult, :conditions => ["age >= 20"]
  named_scope :name_start_with_p,
      lambda {{:conditions => ["name like ?", "'p?'"]}}
  named_scope :older_than, lambda{|n| {:conditions => ["age >= ?", n]}}
  named_scope :name_start_with,
      lambda {|s| { :conditions => ["name like ?", '#{s}}%'] }}
end

>> Person.adult.size
=> 4
>> Person.male.size
=> 3
>> Person.male.adult.size
=> 1
    • Model.scopes
      • Proc の Hash
>> p1 = Person.scopes[:adult]
>> p1.call Person
  => Person.adult
    • 問題は,動的に method_chain を組み立てる方法が難しいということ.
      • eval( "Person.adult.male" ) だとなんだか
      • inject使うとかなんとか.
    • ドキュメントが充実しているらしい

振り返り

まとめへ続く.