[英]How do I select only the associated objects in a Rails “where” query?
I have a model Category, which has_many Products, and a Product in turn has_many Categories. 我有一个模型类别,它有has_many个产品,而一个产品又有has_many个类别。 When a user searches for a Category, I'd like to return the products of the matching Categories without losing my Arel object. 当用户搜索类别时,我想返回匹配类别的产品而不丢失我的Arel对象。 Here's what I have so far: 这是我到目前为止的内容:
Category.where("upper(title) like ?", search_term.upcase).map {|category| category.products}.flatten
This does the trick of returning the products, but of course what I have is an array and not Arel. 这确实有返回产品的技巧,但是我拥有的当然是数组而不是Arel。 I can get as far as adding an :includes(:products)
clause, so I do indeed get the products back but I still have them attached to their categories. 我可以添加一个:includes(:products)
子句,因此确实可以收回产品,但仍将它们附加到其类别中。 How do I adjust my query so that all I get back is an Arel that only addresses products? 如何调整查询,使我得到的只是一个仅解决产品问题的Arel?
If it is products that you want then you should probably start with the Product object when you are searching. 如果是您想要的产品,那么在搜索时可能应该从Product对象开始。 For example ,you could do it like this: 例如,您可以这样做:
Product.joins(:categories).where("upper(categories.title) like ?", search_term.upcase)
The reason I use joins
instead of includes
is that joins will perform an INNER JOIN instead of LEFT OUTER JOIN which is what you need to only return the products that are actually associated with the found categories. 我使用joins
而不是includes
的原因是联接将执行INNER JOIN而不是LEFT OUTER JOIN,这是您只需要返回与找到的类别实际相关联的产品所需要的。
To make it a little more elegant you could wrap it all up in a scope in your Product model like this: 为了使其更加优雅,您可以将其全部包装在产品模型的范围中,如下所示:
# 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])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.