【问题标题】:How do I write a query in Active record for a model that has whos has_many is empty?如何在 Active 记录中为 whos has_many 为空的模型编写查询?
【发布时间】:2025-11-29 14:35:01
【问题描述】:

我的模型会员有很多 DuesPayments。

我想查询 2012 年未缴纳会费的会员。在 DuesPayment 上的字段是 :for_year。或者用英语 - 我希望所有在 dues_payments 表中没有记录的成员都是 2012 年。

#<DuesPayment:0x00000107b3cdd0> {
  :id                      => 1209,
  :member_id               => 446,
  :amount                  => 25.0,
  :created_at              => Thu, 07 Feb 2013 17:01:15 EST -05:00,
  :updated_at              => Thu, 07 Feb 2013 17:01:15 EST -05:00,
  :for_year                => 2013,
  :payment_notification_id => 300
}

好像我需要一个外部连接?问题是,如果尚未付款,则没有记录可供“选择”。

这就是我现在正在做的,它基本上是一个子查询和一个反转。这里的想法是获取所有支付了会费的成员的 ID,然后选择所有不是 THOSE 成员的成员:

scope :dues_not_paid_in, lambda {|year|
  Member.
    where("id not in (?)", 
      DuesPayment.
        select(:member_id).
        where(:for_year => year).
        collect(&:member_id).uniq
  )
}

我的猜测是有一种更优雅的方式来做到这一点。

【问题讨论】:

    标签: ruby-on-rails join rails-activerecord arel


    【解决方案1】:

    您的 dues_payments 模型中是否有某种付费/未付费列?如果是这样,您可以这样做:

    Member.joins(:dues_payments).where("for_year = ? AND paid = ?", 2012, false)
    

    【讨论】:

    • 不,如果他们不付款,那一年根本就没有记录。
    【解决方案2】:

    如果对您的模型有更多了解,这样的事情应该可以工作,如果您需要更多帮助,您可以发布您的模型代码以及我们如何知道付款是否到期。

    unpaid_members = Member.DuesPayments.where(for_year: 2012)
    

    【讨论】:

      【解决方案3】:

      2012 年未缴纳会费的会员

      Member.where("id NOT IN (?)", DuesPayment.select(:member_id).where(:for_year => 2012).map(&:member_id))
      

      【讨论】:

        最近更新 更多