0

現在のプロジェクトではBox、オンライン ストアのアイテムを格納するというモデルがあります。ボックスはPackage(価格、支払い条件などを定義する) に属し、ボックスに含まれる製品と追加のオファーを保持する多くItemのオブジェクトがあります。 顧客が箱に製品と追加のオファーを入れてチェックアウトに進むと、クラスの新しいオブジェクトが作成され、そのアイテムを含む への参照が作成されます。ExtraItem
PurchaseBox

AにはtotalPurchaseという名前の属性があり、(before_validation フックで) アイテムを含むボックスから合計金額を取得し、製品の価格が変わった場合でも支払った合計を記録します。気になるのは、購入が確定して作成された後でも、そのボックスに属するボックスが変更される可能性があり (アイテムの追加/削除が可能)、購入時の現実を反映していない記録が作成されることです。

ボックスへの変更を防ぐために、 after_initialize および initialize メソッドをフックして、ロックされた属性がtrueに設定されている場合に特定の属性変更メソッドが呼び出されないようにするメソッドを作成しました。次のように機能します。

def trigger_locked_box_behavior
  if locked?
    [:items,:extra_items,:garrisons].each { |p| (send("#{p.to_s}")).freeze }
    [:package=, :package_id=, :box_behavior_type=, :resource=, :resource_id=, :resource_type=].each do |param|
      class_eval do
        define_method(param) do |*args|
          raise LockedBoxError
        end
      end
    end
  end
end

基本的に関連付けを凍結し (ボックスには多くのitemextraitems、およびgarrisonsがあります)、特定のメソッドを再定義して、呼び出されたときに LockedBoxError 例外を発生させます。

これは意図したとおりに機能しているように見えるので、このアプローチが予期しない動作を引き起こす可能性があることを本当に心配しており、メソッドをオーバーライドする必要なく同じ効果を達成する方法を探しています!

皆さんは、私がこれを行うことができる方法を知っていますか? あなたの助けに本当に感謝します!:)

4

2 に答える 2

2

readonly! を使用して、レコードを読み取り専用にすることもできます。

ドキュメントはここにあります: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21

于 2011-03-27T09:01:41.983 に答える
2

attr_readonly を使用して、属性を読み取り専用としてマークします。レコードを作成すると作成されますが、その後は更新できません。

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-attr_readonlyを参照してください

于 2011-03-27T01:28:50.167 に答える