Rails 2.1・その6(named_scope がアツい)
-------------------------------------------
controller とかで、:conditions => { ....
とか書いてソースコードがややぐちゃぐちゃになるのを見事にスッキリさせられるようになりました。
早速例を見てみましょう。model クラスに、named_scope の行を追加します。
class Person < ActiveRecord::Base
named_scope :young, :conditions => {:age => 0..30}
end
これで、age が 0 ~ 30 の人をゲットできるようになります。
Person.young
↓
SELECT * FROM "people" WHERE ("people"."age" BETWEEN 0 AND 30)
その人数をカウントしてくれたりもします。
Person.young.count
↓
SELECT count(*) AS count_all FROM "people" WHERE ("people"."age" BETWEEN 0 AND 30)
named_scope は、複数指定することもできますよ。
class Person < ActiveRecord::Base
named_scope :young, :conditions => {:age => 0..30}
named_scope :recent, lambda { {:conditions => ["updated_at > ?", 1.day.ago]} }
end
この :recent ですが、ちょっとわかりづらいのですが、こういう↓変遷をたどりました。
# これだと、リアルタイムの1.day.agoではなく、モデルがインスタンス化された時の1.day.agoがずーっと同じまま残ってしまう
named_scope :recent, :conditions => ["updated_at > ?", 1.day.ago]
# カッコをつけて
named_scope :recent, {:conditions => ["updated_at > ?", 1.day.ago]}
# これが最終形。これだと、:recent が呼び出されるたびに 1.day.ago の値がリアルタイムに変化する
named_scope :recent, lambda { {:conditions => ["updated_at > ?", 1.day.ago]} }
さて本題にもどりますと、:young と :recent を組み合わせることもできます。そうすると、SQL的にはANDでつながるようです。
Person.young.recent
↓
SELECT * FROM "people" WHERE ((updated_at > '2008-05-28 10:55:27') AND ("people"."age" BETWEEN 0 AND 30))
さらに引数を取ってみることもできますよ。
次の例は、引数を取ることもできるし取らなかったら1.day.agoを使う例です。イキナリ複雑でゴメンくさい。
class Person < ActiveRecord::Base
named_scope :recent, lambda {|*args| {:conditions => ["updated_at > ?", args.first || 1.day.ago]} }
end
これを使って
Person.recent(6.days.ago).count
とか出来ちゃいまーす
最後に、named_scope を使わないでも似たようなことができるのでご紹介します
young = Person.scoped(:conditions => {:age => 0..30})
young
↓
SELECT * FROM "people" WHERE ("people"."age" BETWEEN 0 AND 30)
きゃべつ太郎ブンダバー
参考ブログ
named_scope
What's New in Edge Rails: Has Finder Functionality
【広告】