4

由于has_one不提供before_add允许验证的回调,即使新关联未通过验证,如何防止 Rails 破坏旧关联?

苏珊:has_one:衬衫衬衫:belongs_to:苏珊

susan.shirt = a_nice_shirt

这会破坏之前存在的任何关联,即使新衬衫从未真正关联,因为它没有通过验证,留下一个赤膊的苏珊(好吧,实际上留下了一件不属于任何人的衬衫......)。

susan.build_shirt

做同样的事情

before_add我忽略了丢失的回调是否有充分的理由?

4

3 回答 3

2

我不确定为什么没有那个回调,但你总是可以在模型中添加一个观察者,并在 before_save 中验证新的关联。我假设“susan”是一个用户模型实例,并且衬衫必须是红色才能通过验证。

class UserObserver< ActiveRecord::Observer
  def before_save(user)
    return false if user.shirt.color != "red"
  end
end

如果在观察者中返回 false,则对象不会保存。当然,您当前的“susan”实例仍将具有无效关联。我不是很肯定,但是如果您将观察者中的 before_save_ 更改为以下内容:

class UserObserver< ActiveRecord::Observer
  def before_save(user)
    if user.shirt.color != "red"
      user.reload
      false
  end
end

可能会刷新您的用户实例。我从来没有试过这个。

于 2009-07-30T20:44:33.993 回答
0

看这张票:

http://dev.rubyonrails.org/ticket/10518

如果您的关联中有 :dependent => :destroy ,则似乎仍然存在描述的功能。

就个人而言,我认为这是rails中的一个错误。

于 2009-09-25T23:08:06.137 回答
0

在 Rails 中,验证通常在您尝试将对象保存到数据库(使用saveor save!)时完成,而不是在修改时完成。如果出于任何原因您想在验证失败时恢复旧值,您可以使用reload对象或使用新的脏属性功能

于 2009-08-04T18:26:43.623 回答