#ruby-on-rails #ruby #activerecord
#ruby-on-rails #ruby #activerecord
Вопрос:
У меня есть эти модели в моем приложении Rails 4:
class Invoice < ActiveRecord::Base
has_many :allocations
has_many :payments, :through => :allocations
end
class Allocation < ActiveRecord::Base
belongs_to :invoice
belongs_to :payment
end
class Payment < ActiveRecord::Base
has_many :allocations
has_many :invoices, :through => :allocations
end
Очевидно, что возможно, что один payment
принадлежит многим invoices
.
В Payment
модели у меня есть эта функция, которая суммирует общую сумму всех invoices
, к которым относится один конкретный платеж:
def invoice_total_of_siblings
invoice_ids = Allocation.where(:payment_id => id).map(amp;:invoice_id)
invoices = Invoice.where(:id => invoice_ids)
invoices.to_a.sum(amp;:total)
end
Однако эта функция кажется громоздкой, и мне интересно, как ее можно сделать более краткой.
Спасибо за любую помощь.
Комментарии:
1. Вы пробовали
Invoice.where(:id => invoice_ids).sum(:total)
.. Это должно сработать.
Ответ №1:
Используя ваш набор ассоциаций (оплата имеет много счетов-фактур через распределения), вы могли бы просто сделать это:
def invoice_total_of_siblings
invoices.sum(:total)
end
Редактировать:
Это решение работает как есть для полей базы данных, при условии, что данный набор является ассоциацией ActiveRecord.
Однако в данном конкретном случае, поскольку оно получено из комментариев, total
это вычисляемое поле. Следовательно, данный набор будет не ассоциацией ActiveRecord, а массивом. Затем вам нужно будет сопоставить поле, чтобы суммировать его. Правильный синтаксис в этом случае будет:
def invoice_total_of_siblings
invoices.sum(amp;:total)
end
Комментарии:
1. Ах да, спасибо. Намного проще, чем я думал. Однако я должен использовать
amp;:total
, чтобы заставить его работать. Интересно, почему это так.2. @Tintin81 Вы должны использовать
amp;:
, потомуinvoices
что это даст вамArray
Invoice
объекты.3. :total — это поле из таблицы счетов-фактур?
4. @RubyRacer: Нет, он вычисляется из вызываемого поля базы
total_in_cents
данных. Вероятно, поэтому мне нуженamp;
.5. Хорошо, вот почему вам нужно
amp;
… Это отображенное поле… Если это где поле столбца db, то вы не должны ставитьamp;
… Я исправлю свой ответ, чтобы показать это.