Active Record Query Interface上的Rails文档从未如此详尽,API doc也没有多大帮助,所以我从未使用过 QueryMethods# 直到我发现任何现有的ActiveRecord Relation都可以用作子查询。
例如,如果你有
@results= Paper\
.select( :color, :box_id, 'MAX(size) AS maximum_size' )\
.group( :color, :box_id )\
.having( 'AVG(size) > 123' )
您可以将此Relation重用为新查询的中间结果表:
Box.from(@results,:previous_scope)\
.select( :box_id, 'previous_scope.color AS wrap_color')\
.joins( 'LEFT JOIN items USING (box_id)' )\
.where( items: {color:'red'} )
这太棒了,让我免于编写令人讨厌的find_by_sql
语句来构建复杂的查询。
当然,最好定义一些不错的范围来整理代码并避免重复:
class Box < ActiveRecord::Base
scope :suitable_colors, ->(this,color) {
from(this,:previous_scope)\
.select( :box_id, 'previous_scope.color AS wrap_color')\
.joins( 'LEFT JOIN items USING (box_id)' )\
.where( items: {color:color} )
}
end
到目前为止一切顺利,如果像Box.suitable_colors(@results,'green')
一样使用,这将有效。
但是避免将Relation作为参数传递会更好,所以可以像@results.suitable_colors('green')
一样链接它。我使用from(self,:previous_scope)
天真地尝试了不同的方法,但没有成功(最后得到RuntimeError: unsupported: Class
或ArgumentError: A copy of Box has been removed from the module tree but is still active!
)。
问题是@results.is_a? ActiveRecord::Relation
而不是@results.is_a? Box
。是否可以将suitable_colors
定义为Box类中的作用域?