2012-08-10 95 views
13

有人可以解释什么这种方法做什么,我可以传递给它?范围和范围在轨道

scoped(options = nil) 
Returns an anonymous scope. 

还有什么范围方法呢?阅读文档后我不明白。

回答

30

在ActiveRecord的,所有查询的建筑方法(如whereorderjoinslimit等)返回一个所谓的范围。只有当您调用像allfirst这样的踢球者方法时,才会执行构建的查询并返回数据库的结果。

scoped类方法也返回一个作用域。返回的范围默认为空,这意味着结果集不会受到任何限制,这意味着如果执行查询,将返回所有记录。 您可以使用它来提供一个“空白”选项,例如MurifoX的query_by_date示例。 或者你可以用它来多个条件组合成一个方法调用,例如像:

Model.scoped(:conditions => 'id < 100', :limit => 10, :order => 'title ASC') 

# which would be equivalent to 
Model.where('id < 100').limit(10).order('title ASC') 

scope类方法允许你定义一个类的方法也返回一个范围,例如像:

class Model 
    scope :colored, lambda {|col| 
    where(:color => col) 
    } 
end 

可以使用这样的:

Model.colored 

与范围的好处是,你可以将它们组合起来(几乎)如你所愿,所以下面是绝对有可能的:

Model.red.where('id < 100').order('title ASC').scoped(:limit => 10) 

我也强烈建议通过http://guides.rubyonrails.org/active_record_querying.html

+0

谢谢severin,它帮助。我怎么知道我可以传递给.scoped?我看到:conditions => etc. – LuckyLuke 2012-08-10 12:58:26

+1

您可以在这里找到所有选项的完整列表:http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find-label-Options – severin 2012-08-10 14:31:36

+0

真棒!感谢您的帮助 – LuckyLuke 2012-08-10 15:35:59

5

我在past.When用它你让链式调用这样的ActiveRecord查询接口:

Model.where(:conditions).where(:more_conditions).where(:final_conditions) 

他们每个人已经作用域,使得链的工作没有任何问题。但让我们假设你有这样的事情:

Model.query_by_date(date).query_by_user(user).query_by_status(status) 

scope :query_by_date, lambda { |date| 
    case date 
    when "today" 
    where(:date => Date.today) 
    when "tomorrow" 
    where(:date => Date.tomorrow) 
    else 
    # Any value like '' or 0 or Date.whatever 
    end 
} 

如果日期参数不是今天或明天,这会导致错误。它会选择最后一个值,并尝试将此查询与下一个query_by_user链接起来,从而产生undefined method default_scoped? for ''。但是,如果您在else条件中使用了scoped方法,则它的工作方式没有任何缺陷,因为您正在对activerecord说您通过此方法/命名范围并且未对where/find/other activerecord methods进行任何调用,但返回了一个有作用域的对象,所以你可以继续链接查询和东西。
最终会是这样。

else 
    scoped 
end 

希望你明白这个简单的例子。

+0

读你能解释一下这是什么意思是“作用域”? – LuckyLuke 2012-08-10 12:14:59

+1

这就像“是”ActiveRecord兼容。所有ActiveRecords规范封装。 – MurifoX 2012-08-10 12:17:16

+0

我不确定我是否理解“范围”,而不是我理解你的意思......也就是说,我发现否则它就会失败。但我不明白“范围”可以做些什么。 – LuckyLuke 2012-08-10 14:11:59