そのためタイトルを『Rails2.0.3 の named_scope がすごいみたい』から『Edge Rails の named_scope がすごいみたい』に変更しています。
Rails2.0.3 でリリースされるんじゃないかと思われる named_scope がすごいとの話を聞きました。
最近の Rais Dev へのコミットで、named_scope.rb が Active Record へ追加されています。これは has_finder プラグインと似たような機能を提供するものです。
※本エントリは、Ryan’s Scraps の記事のまんまです。
named_scope の基本
まずは基本です。
class User < ActiveRecord::Base # こんな感じで定義する named_scope :active, :conditions => {:active => true} named_scope :inactive, :conditions => {:active => false} named_scope :recent, :conditions => ['created_at > ?', 1.week.ago] end # ふつうの使い方 User.active # User.find(:all, :conditions => {:active => true}) User.inactive # User.find(:all, :conditions => {:active => false}) User.recent # User.find(:all, :conditions => ['created_at > ?', 1.week.ago]) # ネストも可能 User.active.recent # ↓と一緒のこと # User.with_scope(:conditions => {:active => true}) do # User.find(:all, :conditions => ['created_at > ?', 1.week.ago]) # end
このように、User における active、inactive、recent とはどのような条件(状態)かをあらかじめ定義しておくことができるのです。しかもネストもできるので、「アクティブ」かつ「ここ1週間に登録した」ユーザは、User.active.recent とそのまま書くことができるようになるのです。
conditions で長いこと書いたりしていましたが、これですっきり。可読性もかなりあがりますね。
引数を受け取る
引数を取ることもできます。
class User < ActiveRecord::Base named_scope :registered, lambda { |time_ago| { :conditions => ['created_at > ?', time_ago] } end User.registered 7.days.ago # User.find(:all, :conditions => ['created_at > ?', 7.days.ago])
named_scope で何日前かの引数を受ける定義をしています。使い方は 7.days.ago なんかを渡してあげると、そのまま7日前のデータを検索してきます。
named_scope を拡張する
さらに拡張。
class User < ActiveRecord::Base named_scope :inactive, :conditions => {:active => false} do def activate each { |i| i.update_attribute(:active, true) } end end end # inactive なユーザを再度 active に変更 User.inactive.activate
この例では inactive は active が false なものであるという定義の中に、active を true に変更する activate というメソッドを定義しています。
named_scope はかなり使えそう。2.0.3(以上) まで待てないので、rake rails:freeze:edge でとりあえず使ってみようと思います。

