【发布时间】:2014-08-01 09:20:18
【问题描述】:
这是一个示例模型:
class Book < AR::Base
has_many :pages
scope :with_some_conditions, ->(var) {
where(... something with var ...)
.joins(... some joins ...)
}
end
class Page << AR::Base
# Attrs : a, b (integers)
belongs_to :book
scope :with_c, {
select("#{Page.table_name}.*, (a+b) AS c")
}
def c; a+b; end
end
我正在努力获得c 值最大的10 个pages,在某些条件下属于books。
此代码正在运行:
Book.with_some_conditions('foo').map(&:pages).map(&:c)[0...10]
或者更好
Book.with_some_conditions('foo').includes(:pages).map(&:pages).map(&:c)[0...10]
现在想象c 方法不像+ 那样简单,而是一个真的 更复杂的函数(带有连接和其他一些东西)。这段代码只是尽可能地未优化...所有c 必须在 Rails 中计算和排序...SQL 会很有帮助。
在Page 模型中定义范围是我发现的更好的解决方案:
scope :big_scope, ->(var) {
joins(:book)
.where(... something with var ...) # The 2 lines are C/P from Book model
.joins(... some joins ...)
.select("#{Page.table_name}.*, (a+b) AS c")
}
然后,调用Page.big_scope('foo').order(:c => :desc) 就完美了。
问题是我在重复自己:完整的范围在 2 个不同的类中写了 2 次。
.where(... something with var ...)
.joins(... some joins ...)
有什么方法可以通过关系“调用”作用域吗?
问候
【问题讨论】:
-
处理重复的常用方法是将代码放在一个模块中,并将该模块包含在两个类中。
-
@MaxWilliams 如何将 2 个不同类的“范围”包含到一个模块中?
标签: ruby-on-rails ruby-on-rails-4 has-many