0

before_validationコールバックを使用して、レコードの子オブジェクトの数を調整しようとしていますが、何らかの理由で、期待どおりに機能していません。

LineItemクラス:

 before_validation :adjust_enrollment_count

 def adjust_enrollment_count
    if enrollments.size < quantity 
      (enrollments.size+1..quantity).each do |li|
        self.enrollments.build(variant: self.variant)
      end
      #self.save
    elsif enrollments.size > quantity
      enrollments.delete_if do |e| 
        enrollments.size > quantity
      end
    end
  end

何が起こるかというと、LineItemの子として正しい数の登録オブジェクトが作成されますが、Variantはnilに設定されます(LineItemにバリアントが定義されている場合でも)。

私が試したこと:

  • line_itemまたは登録を明示的に保存する
  • コールバックに「こじ開け」てコードを手動で実行します(これは実際には私が期待したとおりに機能しました!)
  • 「自己」がクロージャーではなくLineItemを参照していることを確認する

私が見逃しているコールバックのライフサイクルについて何かありますか?LineItemの数量が変化したときに、登録オブジェクトの数を調整するためのより良い方法はありますか?

4

2 に答える 2

1

おそらくクラスvariantのアクセス可能なフィールドではありません。Enrollmentこの方法を試してください(これも短縮されています)

def adjust_enrollment_count
  while enrollments.size < quantity 
    self.enrollments.build(variant_id: self.variant) # note: variant_id
  end
  while enrollments.size > quantity
    enrollments.pop # or .shift to delete from the head of the list
  end
  # don't save in a lifecycle callback, or you'll get in an awful loop
end

編集:別のテイク

def add_enrollment
  enrollments.build(variant_id: variant)
end

def adjust_enrollment_count
  enrollments.slice!(quantity, enrollments.size)
  add_enrollment while enrollments.length < quantity
end
于 2012-10-30T14:39:29.003 に答える
1

問題は、私の質問で概説していないものであることが判明しました。私は次のように定義しました。

class Enrollment < ActiveRecord::Base
  belongs_to :line_item

  attr_accessible :variant
  attr_accessor   :variant
end

attr_accessor は、ページの読み込み中だけ続くバリアントと呼ばれるメモリ内変数を作成していたと思います。私はそれを削除しましたが、問題は解決したようです。

于 2012-10-30T19:56:05.090 に答える