0

モデルでこの関数を使用してUser、フォームの選択ボックスにデータを入力しています。

def outstanding_invoices
  invoices.to_a.select { |invoice| invoice.balance < 0 }
end

問題は、それbalanceがデータベース フィールドではなく、何かを計算するメソッドであることです。

したがって、選択ボックスを生成するには非常に多くの SQL クエリが必要invoiceですuser

理想的には1つのSQLクエリのみを使用して、選択ボックスを生成するより高速な方法はありますか?

単純な代替手段は、おそらくデータベースbalanceにそれぞれinvoiceを保存することですが、データベースを最小限に抑えたいので、それを行うのはなんとなく気が進まないのです。

助けてくれてありがとう。

4

1 に答える 1

2

計算されたお金の値を扱った経験に基づいて、多くの場合、計算された値をその値の計算に使用されたパラメータとともに保存することは理にかなっています - そうすれば、計算された値に対してクエリを実行できますが、追跡可能性もあります値の計算方法。

after_save請求書の例では、モデルにコールバックを実装することをお勧めしますPayment。例えば:

class Payment < ActiveRecord::Base
  belongs_to :invoice

  def after_save
    invoice.update_balance
  end
end

class Invoice
  has_many :payments

  def self.with_open_balance
    where("current_balance > 0")
  end

  def update_balance
    update_attributes(:current_balance => balance)
  end

  def balance
    invoiced_amount - payments.sum(:amount)
  end
end

このアプローチにより、customer.invoices.with_open_balanceその顧客の未処理の請求書をすべて取得するために電話をかけることができるようになりました。支払いが保存されるたびに、支払いが属する請求書はその残高を再計算し、その計算値を同じデータベース トランザクション内に保存して、一貫性を確保します。

于 2012-10-20T18:02:54.140 に答える