以下是示例模型:
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
我想要获得具有最大pages
值的10 c
,属于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 ...)
是否有通过关系“调用”范围的方法?
此致
答案 0 :(得分:1)
这是标准模块&#39;模板&#39;如果我想在两个或更多类之间共享方法,我会使用。
module MyModule
def self.included(base)
base.extend(ClassMethods)
base.class_eval do
#associations, callbacks, scopes, validations etc go here
end
end
#instance methods go here
module ClassMethods
#class methods go here
end
end