Как мне написать запрос в Active Record для модели, у которой whos has_many пуст?

У меня есть модель Member, у которой много DuesPayments.

Мне нужен запрос для участников, которые не внесли свои взносы в 2012 году. Поле в разделе «Оплата взносов»: 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
}

Кажется, мне нужно внешнее соединение? Проблема в том, что там нет записи, чтобы «выбрать», если платеж не был произведен.

Это то, что я делаю сейчас, это в основном подзапрос и инверсия. Идея здесь состоит в том, чтобы получить идентификаторы всех участников, которые заплатили свои взносы, а затем выбрать всех участников, которые не являются ТЕМИ членами:

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

Я предполагаю, что есть более элегантный способ сделать это.


person pixelearth    schedule 16.02.2013    source источник


Ответы (3)


У вас есть какой-то столбец оплаченных/неоплаченных в вашей модели dues_payments? Если это так, вы можете сделать:

Member.joins(:dues_payments).where("for_year = ? AND paid = ?", 2012, false)
person mind.blank    schedule 16.02.2013
comment
нет, если не платили, то записи за тот год вообще нет. - person pixelearth; 16.02.2013

Не понимая немного больше о ваших моделях, что-то вроде этого должно работать, если вам нужна дополнительная помощь, можете ли вы опубликовать код своих моделей и как мы узнаем, причитается ли платеж или нет.

unpaid_members = Member.DuesPayments.where(for_year: 2012)
person CoderHulk    schedule 16.02.2013

Участники, не внесшие свои взносы в 2012 г.

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