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コールバックでコントリビューションの関連付けを手動で更新する必要があるという事実は奇妙に思えます。
また、非正規化された値は、オブジェクトが永続化されている場合にのみ適切に更新されます。
だから問題は、どうすればこれをより良くすることができ、この種のシナリオのベストプラクティスは何ですか?