轨道中的范围和范围

Luc*_*uke 13 ruby ruby-on-rails ruby-on-rails-3

有人可以解释这种方法的作用以及我可以传递给它的内容吗?

scoped(options = nil)
Returns an anonymous scope.
Run Code Online (Sandbox Code Playgroud)

还有范围方法的作用?阅读文档后我不明白.

sev*_*rin 30

在ActiveRecord的,所有查询的建筑方法(如where,order,joins,limit等)返回一个所谓的范围.仅当您调用类似的踢球者方法allfirst执行构建查询并返回数据库的结果时.

所述scoped类方法也返回一个范围.返回的范围默认为空,这意味着结果集不会受到任何限制,这意味着如果执行查询,将返回所有记录.您可以使用它来提供一个"空"替代方案,就像MurifoXquery_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')
Run Code Online (Sandbox Code Playgroud)

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

class Model
  scope :colored, lambda {|col|
    where(:color => col)
  }
end
Run Code Online (Sandbox Code Playgroud)

可以像这样使用:

Model.colored
Run Code Online (Sandbox Code Playgroud)

范围的好处在于您可以根据需要(几乎)组合它们,因此以下是绝对可能的:

Model.red.where('id < 100').order('title ASC').scoped(:limit => 10)
Run Code Online (Sandbox Code Playgroud)

我还强烈建议您阅读http://guides.rubyonrails.org/active_record_querying.html

  • 从Rails 4开始,`.scoped`已被弃用.`.all`代替`.scoped` http://stackoverflow.com/questions/18198963/with-rails-4-model-scoped-is-deprecated-but-model-all-cant-replace-it/ (2认同)

Mur*_*foX 5

我在过去使用过它.当你对ActiveRecord查询接口进行链式调用时,如下所示:

Model.where(:conditions).where(:more_conditions).where(:final_conditions)
Run Code Online (Sandbox Code Playgroud)

它们中的每一个都已经成为范围,使链条工作没有任何问题.但是,假设您有类似这样的事情:

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
}
Run Code Online (Sandbox Code Playgroud)

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

else
  scoped
end
Run Code Online (Sandbox Code Playgroud)

希望你能理解这个简单的例子.