6

私はかなり典型的な注文モデルを持っていhas_many ます。

class Order < ActiveRecord::Base
  has_many :lines
  validates_associated :lines

注文が完了すると、属性や関連する行を変更することはできません (ただし、ステータスを未完了に変更することはできます)。

  validate do
    if completed_at.nil? == false && completed_at_was.nil? == false
      errors.add(:base, "You can't change once complete")
    end
  end

これは正常に機能しますが、関連するLinesを追加、削除、または変更すると、これは妨げられません。

私のLineモデルでは、次の検証があります。

validate do
  if order && order.completed_at.nil? == false
    errors.add(:base, "Cannot change once order completed.")
  end
end

これにより、完了した注文の明細が変更されるのを正常に停止し、完了した注文に明細が追加されるのを防ぐことができます。

そのため、完了した注文から明細が取り出されないようにする必要もあります。Lineモデルでこれを試しました:

validate do
  if order_id_was.nil? == false
    if Order.find(order_id_was).completed_at.nil? == false
      errors.add(:base, "Cannot change once order completed.")
    end
  end
end

これは、明細を直接変更するときに明細が注文から取り出されるのを防ぐためにうまく機能します。ただし、 Orderを編集してLineを削除すると、 Orderからすでに削除されているため、検証は実行されません。


つまり...要するに、注文に関連付けられた明細が変更されず、追加または削除されないことをどのように検証できますか?

明らかな何かが欠けていると思います。

4

3 に答える 3

5

の「Association Callbacks」セクションから、定義ActiveRecord::Associationsに追加できるいくつかのコールバックがあることがわかります。has_many

  • before_add
  • after_add
  • before_remove
  • after_remove

また、同じドキュメントから:

いずれかのbefore_addコールバックが例外をスローした場合、オブジェクトはコレクションに追加されません。before_removeコールバックと同じです。例外がスローされた場合、オブジェクトは削除されません。

おそらく、コールバック メソッドを に追加しbefore_addbefore_remove、注文が凍結されていないことを確認し、許可されていない場合は例外をスローすることができます。

has_many :lines,
         before_add:    :validate_editable!,
         before_remove: :validate_editable!

private

def validate_editable_lines!(line)
  # Define the logic of how `editable?` works based on your requirements
  raise ActiveRecord::RecordNotSaved unless editable?(line)
end

試してみる価値のあるもう 1 つのことは、検証エラーを追加して、検証テストが失敗した場合に戻ることfalseです。validate_editable_lines!もちろん、それが機能する場合は、メソッド名をvalidate_editable_lines(sans !bang) に変更することをお勧めします。:)

于 2013-09-11T17:09:03.863 に答える
1

おそらくlockedモデルに属性を追加し、注文が完了したら の値をlockedに設定しますtrue。次に、コントローラーで、更新アクションの前にトリガーされる a を追加して、フラグbefore_filterの値をチェックします。lockedに設定されてtrueいる場合、その項目を変更できないというエラー/通知/ユーザーへの何かが発生します。

于 2013-09-11T16:51:18.013 に答える