简体   繁体   English

rails中的has_one关系验证

[英]has_one relationship validation in rails

Since has_one doesn't provide a before_add callback to allow validation, how do I prevent rails from destroying the old association even when the new one does'nt pass validation? 由于has_one不提供允许验证的before_add回调,因此即使新的关联没有通过验证,如何防止rails破坏旧关联?

susan :has_one :shirt shirt :belongs_to :susan 苏珊:has_one:衬衫衬衫:belongs_to:苏珊

susan.shirt = a_nice_shirt susan.shirt = a_nice_shirt

this destroys whatever association was present beforehand, even if the new shirt is never realy associated because it didn't pass validation, leaving a shirtless susan behind (well, acutally leaving a shirt behind that doesn't belong to anyone..). 这会破坏事先存在的任何关联,即使新的衬衫从未真正关联,因为它没有通过验证,留下一个光着膀子的苏珊(好吧,实际上留下一件不属于任何人的衬衫......)。

susan.build_shirt

does the same thing 做同样的事情

Is there a good reason for the missing before_add callback that I overlooked? 我忽略了缺少before_add回调的充分理由吗?

I'm not sure why that callback isn't there, but you can always just add an Observer to the model, and verify the new association in a before_save. 我不确定为什么回调不存在,但你总是可以向模型中添加一个Observer,并验证before_save中的新关联。 I'll assume "susan" is a User Model instance, and the shirt has to be red to pass validation. 我假设“susan”是一个用户模型实例,衬衫必须是红色才能通过验证。

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

If you return false in the observer, the object won't save. 如果在观察者中返回false,则对象将不会保存。 Of course, your current instance of "susan" will still have the invalid association. 当然,您当前的“susan”实例仍然具有无效关联。 I'm not positive, but if you change the before_save_ in the observer to something like this: 我不是肯定的,但如果你将观察者中的before_save_改为这样的话:

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

Might refresh the instance of your User. 可能会刷新用户的实例。 I've never tried this though. 我从来没有试过这个。

In Rails validation is usually done when you try to save the object to the database (using save or save! ), not when it's modified. 在Rails中,通常在尝试将对象保存到数据库时(使用savesave! )进行验证,而不是在修改时。 If for any reason you would like to restore the old value when the validation fails you can either reload the object or use the new dirty attributes feature . 如果出于任何原因,您希望在验证失败时恢复旧值,则可以reload对象或使用新的脏属性功能

Look at this ticket: 看看这张票:

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

It appears that the functionality described there is still present if you have :dependent => :destroy on your association. 如果您在关联上有:dependent =>:destroy,那么它中描述的功能似乎仍然存在。

Personally, I think this is a bug in rails. 就个人而言,我认为这是rails中的一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM