使用accepts_nested_attributes_for进行验证

时间:2015-01-13 23:04:09

标签: ruby-on-rails validation nested-attributes one-to-one

我的rails应用程序的某些代码出现问题,想象一下以下情况:

user.rb

class User < ActiveRecord::Base  
  has_one :participant, dependent: :destroy
  validates_presence_of :username

  accepts_nested_attributes_for :participant
end

participant.rb

class Participant < ActiveRecord::Base  
  belongs_to :user
  validates_presence_of :phone_number
end

运行valid?方法

时会出现问题
user = User.first
user.valid?
#=> true

此时用户验证正常(它只运行来自用户模型的验证),但如果由于某种原因加载了与参与者的关联,那么valid?方法将运行来自用户和来自参与者的验证,其中IMHO错误,因为user是用户模型的实例

user.participant  
Participant Load (0.3ms)  SELECT "participants".* FROM "participants" WHERE "participants"."user_id" = ? LIMIT 1  [["user_id", 1]]  
 => #<Participant id: 1, user_id: 1, phone_number: "", created_at: "2015-01-13 18:15:34", updated_at: "2015-01-13 18:48:27">
user.valid?  
#=>false
user.errors.full_messages  
#=> ["Participant phone number can't be blank"]

如果我在参与者模型中更新某些内容,我会同意此验证,但我不是。这是一个错误还是有任何方法可以跳过相关的验证?

由于

1 个答案:

答案 0 :(得分:0)

在Rails中,嵌套属性将行为传递给父级子级。所以如果你打电话.valid?在父母身上,它将检查所有孩子的验证。这是预期的结构,这是确保关联模型有效的方法,因为您要求它。

我遇到的问题是,如果要跳过验证,为什么要在参与者模型上验证phone_number属性? 您需要删除phone_number的验证或确保存在phone_number。我认为您需要重新评估模型和验证的结构,并考虑到这一点。