Ruby on rails 3.1 Save方法在有效时回滚并返回nil

Ruby on rails 3.1 Save方法在有效时回滚并返回nil,ruby-on-rails-3.1,Ruby On Rails 3.1,我在Rails的save方法上遇到了问题;它似乎在该失败的时候失败了,但在该成功的时候却没有成功 我有一个索赔模型,可以与任何状态一起保存,但如果要提交(状态_id==5),则必须接受条款和条件 validates :terms_and_conditions, :acceptance => {:accept => true, :if => :submitted?} def submitted? # simplified for this example status_id

我在Rails的
save
方法上遇到了问题;它似乎在该失败的时候失败了,但在该成功的时候却没有成功

我有一个
索赔
模型,可以与任何
状态一起保存
,但如果要提交(
状态_id==5
),则必须接受条款和条件

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

def submitted? # simplified for this example
  status_id == 5
end
但是,我还存储了条款被接受的时间(在db field
tnc_accepted_at
下),并将
条款和条件定义为该字段的存在。(这一点很好,我只是不确定它是否与我的问题有关。)

但问题是。索赔从以下状态开始:

claim
 => #<Claim id: 51, tnc_accepted_at: nil, status_id: 4>
claim.valid?
 => true
。。。这很完美,但当我试图纠正错误时:

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\u attributes
update\u attributes!
:tnc\u accepted\u at=>DateTime。现在
,这无关紧要)-如果它有效,它会回滚并返回nil;如果它是无效的,则会像您预期的那样出现错误。

当然,在我花了一整天的时间之后,这是一件非常简单的事情

因此,
update\u 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!
>索赔
=> #
>索赔有效吗?
=>正确
#=========
>认领。保存——这一切都不同!
(0.3ms)开始
索赔负载(0.4ms)选择--诸如此类诸如此类
(1.0ms)插入“索赔”--诸如此类
(14.8ms)提交
=>正确
#=========
>claim.update_属性!:状态_id=>5
(0.3ms)开始
ClaimItem加载(1.5ms)选择--诸如此类诸如此类
状态加载(0.6ms)选择--诸如此类诸如此类
(0.4ms)回滚
ActiveRecord::RecordInvalid:验证失败:必须接受条款和条件
# ... 正如所料。
>claim.update_属性!:术语和条件=>true
(0.3ms)开始
ClaimItem加载(0.8ms)选择--诸如此类诸如此类
(0.8ms)更新“索赔”--诸如此类
(11.4ms)提交
=>正确
# ... 好极了

当然,在我花了一整天的时间之后,这件事真的很简单

因此,
update\u 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!
>索赔
=> #
>索赔有效吗?
=>正确
#=========
>认领。保存——这一切都不同!
(0.3ms)开始
索赔负载(0.4ms)选择--诸如此类诸如此类
(1.0ms)插入“索赔”--诸如此类
(14.8ms)提交
=>正确
#=========
>claim.update_属性!:状态_id=>5
(0.3ms)开始
ClaimItem加载(1.5ms)选择--诸如此类诸如此类
状态加载(0.6ms)选择--诸如此类诸如此类
(0.4ms)回滚
ActiveRecord::RecordInvalid:验证失败:必须接受条款和条件
# ... 正如所料。
>claim.update_属性!:术语和条件=>true
(0.3ms)开始
ClaimItem加载(0.8ms)选择--诸如此类诸如此类
(0.8ms)更新“索赔”--诸如此类
(11.4ms)提交
=>正确
# ... 好极了

也许这个问题太老了

我认为问题在于
“新记录”
标志(如您所建议的)。如果保存新记录,
“新记录”
将设置为false,good,但如果有回滚,
“新记录”
仍将具有值false,就像保存中其他填充的列将保留其值一样。 如果尝试了新的保存(使用正确的值),Rails中的
save
方法将执行db更新而不是db插入,因为
“new record”
为false

我在一个非常旧的Rails版本中注意到了这一点,我认为它现在已经被修复了。我在ActiveRecord::Base中用这个方法修复了它(Rails必须在内部使用@new\u record才能工作)


也许这个问题太老了

我认为问题在于
“新记录”
标志(如您所建议的)。如果保存新记录,
“新记录”
将设置为false,good,但如果有回滚,
“新记录”
仍将具有值false,就像保存中其他填充的列将保留其值一样。 如果尝试了新的保存(使用正确的值),Rails中的
save
方法将执行db更新而不是db插入,因为
“new record”
为false

我在一个非常旧的Rails版本中注意到了这一点,我认为它现在已经被修复了。我在ActiveRecord::Base中用这个方法修复了它(Rails必须在内部使用@new\u record才能工作)


ActiveRecord
save
方法返回nil的另一个原因是它是否被模拟。类似于
expect(modelInstance).to receive(:save)

ActiveRecord
save
方法返回nil的另一个原因是如果它被模拟。类似于
expect(modelInstance)。接收(:save)

版本:rails 3.1.0;pg0.11;“x86_64-unknown-linux-gnu上的PostgreSQL 9.1.5,由gcc(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3编译,64位”(Ubuntu 12.04“精确穿山甲”)。想不出任何其他相关的东西。我没有将
状态
验证器直接放在
tnc_accepted_at
上的原因是该字段不在视图中;相反,我有一个
术语和条件
复选框,我希望出现与此相反的错误。另外,在新的
声明
上尝试此操作时,
id
处创建和
处更新字段确实会被填充,Rails认为它不再是新记录。希望这将有助于确定问题发生的位置…版本:rails 3.1.0;pg0.11;“x86_64-unknown-linux-gnu上的PostgreSQL 9.1.5,由gcc(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3编译,64位”(Ubuntu 12.04“精确穿山甲”)。想不出任何其他相关的东西。r
> 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!
def try_reset_new_record!
  if ! self.new_record? &&
      ( ! self.id || ! self.class.find_by_id(self.id) )
    @new_record = true
  end
end