【问题标题】:Rails 3.2: Chaining lambda scopes?Rails 3.2:链接 lambda 范围?
【发布时间】:2012-09-23 17:29:42
【问题描述】:

在我的 Rails 3.2.8 应用程序中,我有一些命名范围,我想在某些情况下将它们链接在一起。

因此,例如,我有这两个范围:

scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
scope :in_date_range, lambda { |start_date, end_date| includes([:person, :pier_module]).where("(status_date >= ?) AND (status_date <= ?)", start_date, end_date) }

我单独使用它们,但我也希望能够像这样一起调用它们:

WorkRequest.by_status("Accepted").in_date_range("2012-01-01", "2012-10-02")

当我尝试它抱怨 in_date_range 不是 Array 的方法时。

但我有另一个范围,

scope :active, includes([:person, :pier_module]).where("status = 'New Request'")

如果我这样做了

WorkRequest.active.in_date_range("2012-01-01", "2012-10-02")

有效!显然活动范围返回一个关系,而 lambda 范围返回数组,因此不能被链接。

我很想知道为什么更简单的作用域和 lambda 作用域之间的区别,参数如何影响它,以及除了我已经完成的编写组合作用域之外我还能做些什么。

scope :by_status_in_date_range, lambda { |status, start_date, end_date|  includes([:person, :pier_module]).where("(status = ?) AND (status_date >= ?) AND (status_date <= ?)", status, start_date, end_date) }

有效,但不是很干燥(因为我也需要单独的范围)或 Rails 风格。在这里和其他地方搜索时,我看到了类似的问题,但似乎没有一个适用于这种情况,我试图用参数链接两个 lambda。

【问题讨论】:

  • 只是出于好奇,WorkRequest.in_date_range("2012-01-01", "2012-10-02").by_status("Accepted") 有效吗?
  • 我愿意!我太“有远见”而无法尝试。我确信这是由于 lambdas,但显然不是。这很棒,我可以这样称呼它,但仍然让我想知道为什么 in_date_range 返回一个关系,而 by_status 一个数组。越来越好奇。

标签: ruby-on-rails named-scopes


【解决方案1】:

这是因为在你的范围内

scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }

metods allfind_all_by_status 返回 Array 而不是 ActiveRecord::Relation。例如,您应该将其替换为 where

scope :by_status, lambda { |status| where(:status => status) unless status == "All" }

【讨论】:

  • 谢谢,ck3g,这很有道理!我会看看是否可以将其更改为返回关系。
  • 链式作用域的威力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多