在我的 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) }

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

有帮助吗?

解决方案

发生这种情况是因为在你的范围内

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

方法 allfind_all_by_status 回报 Array 代替 ActiveRecord::Relation. 。你应该将其替换为 where 例如。

scope :by_status, lambda { |status| where(:status => status) unless status == "All" }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top