0

Rails3.0を使用したギフトレジストリアプリに取り組んでいます。アプリは、複数のゲストが贈り物に貢献することを可能にします。ギフトを表示するときは、残りの金額を表示する必要があります。合計金額が指定されている場合は、購入したアイテムを表示する必要があります。

パフォーマンスのために、貢献の合計とアイテムのステータスを非正規化したいと思います。

簡単そうに見えますが、これを完全にカプセル化された方法でモデルに配置する方法を見つけようとすると、すべての状況で機能するため、予想よりもはるかに複雑になりました。

アイテムとコントリビューションの関連付けに関するコールバックを含むいくつかの異なるアプローチを試しましたが、最終的にはコントリビューションオブジェクトに対するコールバックになりました。

item.rb

class Item < ActiveRecord::Base
  # decimal amount

  # decimal total_contributed
  # boolean purchased
  has_many :contributions, :inverse_of => :item

  def set_total_contributed
    self.total_contributed = 0
    contributions.each do |cont|
      self.total_contributed += cont.amount
    end
    purchased = self.total_contributed >=  amount
  end
end

order.rb

class Order < ActiveRecord::Base
  has_many :contributions, :inverse_of => :order, :dependent => :destroy
end

寄稿.rb

class Contribution < ActiveRecord::Base
  belongs_to :item, :inverse_of => :contributions
  belongs_to :order, :inverse_of => :contributions

  after_create do |cont|
    item.set_total_contributed
    item.save
  end

  after_destroy do |cont|
    item.contributions.delete(cont)
    item.set_total_contributed
    item.save
  end
end

これは私が必要とする状況で機能するように見えますが、正しく感じられません。

まず、destroyコールバックでコントリビューションの関連付けを手動で更新する必要があるという事実は奇妙に思えます。

また、非正規化された値は、オブジェクトが永続化されている場合にのみ適切に更新されます。

だから問題は、どうすればこれをより良くすることができ、この種のシナリオのベストプラクティスは何ですか?

4

0 に答える 0