0

Rails のsave方法に問題があります。あるべきときに失敗しているように見えますが、あるべきときに成功していません。

Claim任意の で保存できるモデルがありますがStatus、それを送信する場合 ( status_id == 5)、利用規約に同意する必要があります。

validates :terms_and_conditions, :acceptance => {:accept => true, :if => :submitted?}

def submitted? # simplified for this example
  status_id == 5
end

ただし、条件が受け入れられた時刻も ( db フィールドの下に) 保存し、このフィールドの存在としてtnc_accepted_at定義しています。terms_and_conditions(このビットは正常に動作しますが、それが私の問題に関連しているかどうかはわかりません。)

def terms_and_conditions
  tnc_accepted_at.present?
end

def terms_and_conditions=(bool) # browser will pass '0' or '1'
  self.tnc_accepted_at = bool.in?([false, nil, 0, '', '0']) ? nil : DateTime.now
end

しかし、ここに問題があります。クレームは次の状態から始まります。

claim
 => #<Claim id: 51, tnc_accepted_at: nil, status_id: 4>
claim.valid?
 => true

それから私はそれを提出しようとします:

claim.update_attributes! :status_id => 5
   (0.3ms)  BEGIN
  ClaimItem Load (1.5ms)  SELECT --blah blah blah
  Status Load (0.6ms)  SELECT --blah blah blah
   (0.4ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Terms and conditions must be accepted

...これは完璧ですが、エラーを修正しようとすると:

claim.update_attributes! :terms_and_conditions => true
   (0.3ms)  BEGIN
  ClaimItem Load (1.1ms)  SELECT --blah blah blah
   (0.7ms)  UPDATE "claims" --blah blah blah
   (0.2ms)  ROLLBACK
 => nil

...それはただ奇妙です! そして、レコードを保存しようとすると、どのような状況でも ( save, save!, update_attributes,update_attributes!を使用:tnc_accepted_at => DateTime.nowしても問題ありません) 、有効な場合はロールバックして nil を返します。invalidの場合、期待どおりにエラーが発生します。

4

3 に答える 3

2

saveActiveRecordメソッドが nil を返すもう 1 つの理由は、モックされている場合です。何かのようなものexpect(modelInstance).to receive(:save)

于 2016-09-30T00:45:22.973 に答える
2

おそらく、この質問は古いですか?

"new record"問題はフラグだと思います(あなたが示唆したように)。新しいレコードが保存された場合、"new record"は false に設定されますが、ロールバックが発生した場合"new record"でも、 の値は false のままです。これは、保存時に入力された他の列の値のままです。新しい保存が (正しい値で) 試行saveされると、Rails のメソッドは db-insert の代わりに db-update を実行し"new record"ます。

非常に古いバージョンのRailsでこれに気づき、今では修正されるだろうと思っていました。ActiveRecord::Base のこのメソッドで修正しました (これを機能させるには、Rails がまだ内部で @new_record を使用している必要があります)。

def try_reset_new_record!
  if ! self.new_record? &&
      ( ! self.id || ! self.class.find_by_id(self.id) )
    @new_record = true
  end
end
于 2012-11-19T02:47:56.833 に答える
0

当然のことながら、丸一日かけて作ったものはとてもシンプルです...

したがって、すでに保存されているupdate_attributesレコードに対してのみ適切に機能するようです。

> claim
 => #<Claim id: 51, tnc_accepted_at: nil, status_id: 4>
> claim.valid?
 => true
#=========
> claim.save # This makes all the difference!
   (0.3ms)  BEGIN
  Claim Load (0.4ms)  SELECT --blah blah blah
   (1.0ms)  INSERT INTO "claims" --blah blah blah
   (14.8ms)  COMMIT
 => true
#=========
> claim.update_attributes! :status_id => 5
   (0.3ms)  BEGIN
  ClaimItem Load (1.5ms)  SELECT --blah blah blah
  Status Load (0.6ms)  SELECT --blah blah blah
   (0.4ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Terms and conditions must be accepted
# ... just as expected.
> claim.update_attributes! :terms_and_conditions => true
   (0.3ms)  BEGIN
  ClaimItem Load (0.8ms)  SELECT --blah blah blah
   (0.8ms)  UPDATE "claims" --blah blah blah
   (11.4ms)  COMMIT
 => true
# ... hooray!
于 2012-08-29T22:30:25.393 に答える