【问题标题】:Validations with accept_nested_attributes_for使用 accept_nested_attributes_for 进行验证
【发布时间】:2023-03-05 19:42:02
【问题描述】:

我的 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? 方法将从 用户 运行验证> 并且来自 Participant 恕我直言是错误的,因为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"]

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

谢谢

【问题讨论】:

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


    【解决方案1】:

    在 Rails 中,嵌套属性将行为传递给父子级。那么如果你调用.valid?在父级上,它将检查所有子级的验证。这是预期的结构,并且是确保关联模型有效的方式,因为您要求它是有效的。

    我的问题是,如果您想跳过验证,为什么要在 Participant 模型上验证 phone_number 属性? 您要么需要删除 phone_number 的验证,要么确保 phone_number 存在。我认为您需要重新评估模型的结构和验证。

    【讨论】:

    • 感谢您的 cmets,模型假设所有业务逻辑都被隔离了,我验证了 phone_number 因为这是 Participant 模型应该工作的方式(虽然这是一个例子,我有更多在我的真实模型中进行验证)。我明白你在说什么,但这对我来说似乎有点尴尬,因为我没有修改参与者模型中的任何内容,也许还有另一种方法可以做到这一点。
    • 嗨,Richard,模型的逻辑确实与特定模型隔离,这是真的。但是,当您将参与者模型嵌套在用户模型下时,您实际上是在对两个模型执行操作,从而在两者上调用验证。这是嵌套关联如何工作的另一个示例:当您执行 User.save 时,它​​将对关联的 Participant 模型执行 .save 以保存嵌套模型的属性。同样的逻辑适用于运行 .valid?它会运行 .valid 吗?在父级和嵌套子级上,因为这是嵌套模型时所期望的。
    • 正确,但问题是 valid? 方法将在两个模型(UserParticipant)中运行,前提是加载了关系(在 accepts_nested_attributes_for 中使用) .
    • 在上面的示例中,您正在测试的用户 (id => 1) 具有关联的参与者 (participant_id => 1),因此您加载了它,因此它会在以下情况下加载该用户的参与者模型验证你运行user.valid?并且验证失败,因为关联的参与者没有有效的电话号码。
    • 也许看看这个线程......也许它对你有用。 stackoverflow.com/questions/9529766/…
    猜你喜欢
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多