14

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

scoped(options = nil)
Returns an anonymous scope.

还有作用域方法的作用是什么?看文档后我不明白。

4

2 回答 2

31

在 ActiveRecord 中,所有查询构建方法(如whereorderjoinslimit)都返回一个所谓的范围。仅当您调用类似的 kicker 方法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

于 2012-08-10T12:49:26.923 回答
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

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

于 2012-08-10T11:51:09.010 回答