我正在使用 Rails 3.2。
我有一个产品模型和一个变体模型。一个产品可以有许多变体。一个变体可以属于许多产品。
我想查找 Products 模型,只查找具有特定变体计数的产品,例如(伪代码):
Product.where("Product.variants.count == 0")
你如何用activerecord做到这一点?
我正在使用 Rails 3.2。
我有一个产品模型和一个变体模型。一个产品可以有许多变体。一个变体可以属于许多产品。
我想查找 Products 模型,只查找具有特定变体计数的产品,例如(伪代码):
Product.where("Product.variants.count == 0")
你如何用activerecord做到这一点?
您可以使用 aLEFT OUTER JOIN
返回您需要的记录。RailsLEFT OUTER JOIN
在您使用includes
.
例如:
Product.includes(:variants).where('variants.id' => nil)
这将返回所有products
没有variants
. 您还可以使用显式joins
.
Product.joins('LEFT OUTER JOIN variants ON variants.product_id = products.id').where('variants.id' => nil)
将LEFT OUTER JOIN
返回连接左侧的记录,即使右侧不存在。它将null
值放入关联的列中,然后您可以使用它们来检查是否存在,就像我在上面所做的那样。您可以在此处阅读有关左连接的更多信息:http: //www.w3schools.com/sql/sql_join_left.asp。
这个解决方案的好处是您没有将子查询作为条件进行,这很可能会提高性能。
products= Product.find(:all,:select => 'variant').select{|product| product.varients.count > 10}
这是 rails 2.3 ,但只有 activeRecord 部分,您需要查看该select
部分
我不知道有任何 ActiveRecord 方法可以做到这一点,但以下内容应该有助于解决您的问题。这个解决方案的好处是一切都在数据库端完成。
Product.where('(SELECT COUNT(*) FROM variants WHERE variants.product_id = products.id) > 0')
如果您想提取具有特定非 0 变体数量的产品,您可以使用以下方式执行此操作(诚然未经测试):
Product.select('product.id, product.attr1_of_interest, ... product.attrN_of_interest, variant.id, COUNT(*)')
.joins('variants ON product.id = variants.product_id')
.group('product.id, product.attr1_of_interest, ... product.attrN_of_interest, variant.id')
.having('COUNT(*) = 5') #(or whatever number manipulation you want to do here)
如果您想允许 0 个产品,则必须使用上述 Sean 的解决方案。