我正在模型中构建一系列方法以用作范围。当其中一个使用having子句并且该查询没有返回任何结果时,我得到一个返回模型的实例,其中所有字段都是nil,并且这打破了我想要使用这些范围的大多数代码。
下面是一个高度简化的示例,用于演示我的问题。
class Widget < ActiveRecord::Base
attr_accessible :name
has_many :components
def without_components
joins(:components).group('widgets.id')having('COUNT(components.id) = 0')
end
def without_components_and_remove_nil
without_components.select{|i| i.id} # Return objects where i.id is not nil
end
end
如果所有窗口小部件都已分配了组件,则调用Widget.without_components
将返回不合需要的内容:
[{id: nil, name: nil, user_id: nil}]
但是如果我调用Widget.without_components_and_remove_nil
它会将ActiveRecord::Relation
对象转换为Array
,因此我无法将其与其他作用域链接起来。< / p>
是否有办法更改范围,以便在出现nil行时将其排除,或者是否可以对我的ActiveRecord查询进行修改以使其有效?
答案 0 :(得分:0)
我需要解决两个问题才能使该范围有效;一个与我原来的问题没有关系的,虽然上面提到的范围在没有它的情况下不会被修复:
Widget.where(id: Widget.joins(:components).group('widgets.id').having('COUNT(components.id)'))
joins(:components)
部分无法与having('COUNT(components.id = 0)')
一起使用,因为joins
执行内部联接,因此该查询永远不会有任何结果。我必须将joins
替换为joins("LEFT OUTER JOIN components ON components.widget_id = widgets.id")
。