如何仅选择Rails“where”查询中的关联对象?

时间:2012-04-24 01:48:32

标签: ruby-on-rails activerecord

我有一个型号类别,其中包含has_many产品,另一个产品包含has_many类别。当用户搜索类别时,我想返回匹配类别的产品而不会丢失我的Arel对象。这是我到目前为止所做的:

Category.where("upper(title) like ?", search_term.upcase).map {|category| category.products}.flatten

这就是返回产品的诀窍,但当然我拥有的是阵列而不是Arel。我可以添加一个:includes(:products)条款,所以我确实得到了产品,但我仍然将它们附加到它们的类别中。如何调整我的查询以便我得到的只是一个仅针对产品的Arel?

1 个答案:

答案 0 :(得分:3)

如果是您想要的产品,那么您在搜索时应该从Product对象开始。例如,您可以这样做:

Product.joins(:categories).where("upper(categories.title) like ?", search_term.upcase)

我使用joins而不是includes的原因是,连接将执行INNER JOIN而不是LEFT OUTER JOIN,这是您只需返回与找到的类别实际关联的产品

为了使它更优雅,你可以将它全部包装在Product模型的范围内,如下所示:

# 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])