私は請求書と支払いのためのシンプルな正規化モデルを持っています。私はRuby on Railsの未払い金額にdenormaizedフィールドを使用する必要があります
関連分野が
invoices.id
invoices.amount_with_tax
invoice_payments.id
invoice_payments.invoice_id
invoice_payments.amount
関係が
Invoice
has_many :invoice_payments
has_many :payments, through: :invoice_payments
InvoicePayment
belongs_to :invoice
belongs_to :payment
Payment
has_many :invoice_payments
has_many :invoices, through: :invoice_payments
されている支払モデルは、この質問には関係ありませんが、同じ問題を呈します。
変数invoices
と@invoices
は、アクティブレコード関係です。
私は、請求書テーブルにamount_outstanding
フィールドを追加した場合、未払いの請求書を取得するためのコードは単純です:
invoices.where('amount_outstanding > 0')
が、非正規化フィールドの維持は迷惑です。そのフィールドなしでこれを取得する
私の現在のコードは複雑です:
invoices = invoices.left_outer_joins(:invoice_payments)
invoices = invoices.distinct.select('invoices.*, sum(invoice_payments.amount) as total_payments')
invoices = invoices.group('invoices.id')
invoices = invoices.having('sum(invoice_payments.amount) < invoices.amount_with_tax or sum(invoice_payments.amount) is null')
私はこの上の任意のパフォーマンステストを行っていないが、多くのがあるとき、それは非常に良いことはありませんように見えますシステム内の請求書。 ActiveRecordで生成されるコードは、SQLで記述したコードと似ていますので、恐ろしいことではありません。
請求先に完全には記載されていない支払いを見つけるには、支払い側で同様のコードが必要になります。
未払いの請求書を検索すると、未払いの金額が報告されるため、頻繁な操作です。堅実に運営されている会社にとっては、未収入金の未収金額は支払った金額に比べて少ない。時間が経つにつれて、それは全体の請求書の中ではるかに少ない割合になります。
請求書に支払いを適用するのは通常1回で、復帰や編集はほとんどありません。ほとんどの支払いは1つの請求書に関連し、それを完全にカバーします。
未払いの請求書があるかどうかを判断したり、erbでカウントを取得しようとしています。 <%[email protected] %>
はSQLエラーを返します。
私は個人的に非正規化されたデータを好きではありません。それは、それを維持する作業が正規化されたままにしておくのが普通の約3倍であるからです。この場合、amount_with_tax
が変更された場合、またはInvoicePayment
が編集、削除、または別の請求書に移動された場合は、項目を更新する必要があります。 amount_outstandingの値を計算するためのコードは、しかし、単一の請求書のために非常に簡単です:
paid = invoice_payments.sum(:amount)
self.amount_outstanding = self.amount_with_tax - paid
save
私は現在amount_outstanding
を維持するために、請求書やInvoicePaymentsモデルにコールバックを使用しています。
質問があります。この場合、価値のある非正規化フィールドがありますか、これを実現するにはより良い方法がありますか?
請求書の更新に関する問い合わせの頻度はおそらく100対1程度です。最終的なシステムのサイズはわかりませんが、拡張の能力を制限したくありません。典型的な中小企業の場合、年に数千の請求書がありますが、それほど大きなものではありません。カウントを取得するエラーを除いて正規化されたコードが実行され、別のクエリを書き込むことができます。そして私は早すぎる最適化についてDKに同意します。 –
何千もの請求書は心配するほど大きな数字ではありません。したがって、非正規化されていないフィールドを使用しないで開始する方が良いと思われ、必要に応じて最適化を行います。また、カウントについては、モデルやコントローラーでカウントを取得し、そのコードをerbに直接書き込むのではなくerbに渡すコードを書く方が良いです。 – coffeebytes