我有一个模型类别,它has_many产品,还有一个产品又has_many类别。当用户搜索类别时,我想返回匹配类别的产品,而不会丢失我的 Arel 对象。这是我到目前为止所拥有的:
Category.where("upper(title) like ?", search_term.upcase).map {|category| category.products}.flatten
这可以解决问题,但当然我拥有的是一个数组而不是 Arel。我可以添加一个:includes(:products)
条款,所以我确实得到了产品,但我仍然将它们附加到它们的类别中。如何调整查询,以便我得到的只是仅针对产品的 Arel?
如果你想要的是产品,那么在搜索时,你应该从 Product 对象开始。例如,你可以这样做:
Product.joins(:categories).where("upper(categories.title) like ?", search_term.upcase)
我使用 joins
而不是 includes
的原因是,联接将执行内部联接而不是左外联接,这是您只需要返回实际与找到的类别关联的产品所需要的。
为了使它更优雅一点,您可以将其全部包装在产品模型的范围内,如下所示:
# In Product.rb
scope :in_categories_like, Proc.new{ |search_term|
joins(:categories).where("upper(categories.title) like ?", search_term.upcase)
}
# In use
@products = Product.in_categories_like(params[:search_term])