Learn how to use with_scope - a very powerful method which will allow your custom find methods to accept any find options. Just like magic!
这一节学习如何使用with_scope-一个非常强大的方法,利用这个方法可以使得自定义的find方法接受更多的参数。
 
InBlock.gif# models/task.rb
InBlock.gifdef self.find_incomplete(options = {})
InBlock.gif    with_scope :find => options do
InBlock.gif        find_all_by_complete( false, :order => 'created_at DESC')
InBlock.gif    end
InBlock.gifend
 
过程:
 
首先是在task.rb中
 
def self.find_incomplete
    find_all_by_complete(false, :order=>'created_at DESC')
end
 
针对这个find方法
如果现在有需求,要求显示前20条
 
那么在controller中,在调用find_incomplete时,加上一个参数:limite=>20
在task.rb中修改self.find_incomplete方法:
 
InBlock.gif# models/task.rb
InBlock.gifdef self.find_incomplete(options = {})
InBlock.gif    with_scope :find => options do
InBlock.gif        find_all_by_complete( false, :order => 'created_at DESC')
InBlock.gif    end
InBlock.gifend
 
在railsbrain文档中对with_scope的说明:
 
 
with_scope(method_scoping = {}, action = :merge) {|| ...}
Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. method_name may be   :find  or   :create.   :find  parameters may include the   :conditions,   :joins,   :include,   :offset,   :limit, and   :readonly  options.   :createparameters are an attributes hash.
在block中调用scope参数。用一个hash作为方法名的参数。方法名可以是:find或者:create. :find可以包含:conditions, :joins, :include, :offset, :limit 和:readonly这些hash选项。:create参数是一个属性hash。
  class Article < ActiveRecord::Base
    def self.create_with_scope
      with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do
        find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
        a = create(1)
        a.blog_id # => 1
      end
    end
  end
In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of   :conditions  and :include  options in   :find, which are merged.
 
  class Article < ActiveRecord::Base
    def self.find_with_scope
      with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
        with_scope(:find => { :limit => 10 })
          find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
        end
        with_scope(:find => { :conditions => "author_id = 3" })
          find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
        end
      end
    end
  end
You can ignore any previous scopings by using the   with_exclusive_scope  method.
  class Article < ActiveRecord::Base
    def self.find_with_exclusive_scope
      with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }) do
        with_exclusive_scope(:find => { :limit => 10 })
          find(:all) # => SELECT * from articles LIMIT 10
        end
      end
    end
  end