轨道中的范围和范围

时间:2012-08-10 10:45:23

标签: ruby-on-rails ruby ruby-on-rails-3

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

scoped(options = nil)
Returns an anonymous scope.

范围方法的作用是什么?阅读完文档后我不明白。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:5)

我过去曾经使用过它。当您对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 ''。但是如果你在scoped条件下放置一个else方法,那么它就会没有任何缺陷,因为你说要通过这个方法/命名范围并且没有调用任何调用的activerecord where/find/other activerecord methods,但返回了一个范围对象,因此您可以继续链接查询和内容 最终会是这样的。

else
  scoped
end

希望您能理解这个简单的例子。