Ruby on rails 查找关联记录仅具有特定属性值的所有记录

Ruby on rails 查找关联记录仅具有特定属性值的所有记录,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,比如说,我有两种型号的产品和付款方式,它们之间有很多联系 class Product < ApplicationRecord has_many :payments end class Payment < ApplicationRecord belongs_to :product end 但它返回的产品中至少有一笔付款是假的,而我需要所有付款都是假的。我认为这可能会满足您的要求: Product. where(id: Payment.where(paid: false).

比如说,我有两种型号的产品和付款方式,它们之间有很多联系

class Product < ApplicationRecord
  has_many :payments
end
class Payment < ApplicationRecord
  belongs_to :product
end
但它返回的产品中至少有一笔付款是假的,而我需要所有付款都是假的。

我认为这可能会满足您的要求:

Product.
  where(id: Payment.where(paid: false).pluck(:product_id)).
  where.not(id: Payment.where(paid: true).pluck(:product_id))
我是gem的忠实粉丝,它使用ActiveRecord简化了很多查询

您正在寻找只有false付款的产品,因此您可以在ransack查询中添加两个子句以实现所需的结果

首先安装ransack,然后使用它查看您是否获得了所需的结果

Product.ransack(
  payments_paid_eq: false, 
  payments_paid_not_eq: true)
.result
.distinct
在某些方面,这是一个稍微令人困惑的查询,但本质上,您是说返回所有付款为false的产品,而不返回付款为true的产品

不使用ransack gem的替代方法如下

Product.joins(:payments)
  .where(payments: {paid: false})
  .where.not(payments: {paid: true})
  .distinct

在这里更喜欢选择而不是拔出,使用子查询而不是推送大的id列表。@matthewd你的意思是像Payment.WherePaymed:false.select:product\u id?是的,正是如此。@matthewd-我总是对选择v拔出感到困惑。我的印象是select实例化了付款记录,而PULLC没有。在这种情况下,这不会发生吗?还有很多东西要学。select返回一个[延迟]关系;Pull运行查询并返回一个数组。如果我们在结果上循环,那么pull将更有效-但是当我们将其作为查询条件传回时,仍然没有执行的关系可以更有效地处理。
Product.joins(:payments)
  .where(payments: {paid: false})
  .where.not(payments: {paid: true})
  .distinct