如何在 has_many 关联中使用嵌套属性查找验证失败的记录?

How to find the record that failed in validation with nested attributes on a has_many association?

假设我有这个:

class Author < ActiveRecord::Base  
  has_many :posts
  accepts_nested_attributes_for :posts
end

class Post < ActiveRecord::Base  
  belongs_to :author
  validates_presence_of :name
end

前端有一个一次性保存所有内容的表单,一个作者和你想要的post,发送这个输入:

attributes = { name: "lorem",
  posts_attributes: [
    { name: 'lorem',
      order: 1 },
    { name: 'lorem',
      order: 2 }
   ] 
}
author = Author.new(attributes)
author.save

我的问题是关于验证的。我如何将验证发回前端,以便它能够以 Post 实例失败的形式理解?现在,输入如下:

attributes = { name: "lorem",
  posts_attributes: [
    { order: 1 },
    { name: 'lorem',
      order: 2 }
   ] 
}
author = Author.new(attributes)
author.save

author.errors.messages 将 return 类似 {:"posts.name"=>["must be present"]} 的东西,但没有指示知道将验证错误发送到表单中的哪个 name 字段,因为有多个 post 正在创建。

如何通过使用每个 Post 实例也具有的 order 属性来更改此错误以获得此指示?

编辑:我想要另一个像 order: 1 这样的键值对,而不是自定义验证错误,包括错误消息中的数字顺序,以便在前端更容易处理

如果您想获得更具体的验证消息,则必须在 Post 模型中创建自己的验证函数,而不是使用 presence 选项。

Post.rb

validate :validate_name_present

...

private

def validate_name_present
  return if name.present?
  errors.add(:name, "must be present" + (order.present? ? " for order #{order}" : ""))
end

这是我需要的解决方案:https://bigbinary.com/blog/errors-can-be-indexed-with-nested-attrbutes-in-rails-5

基本上将 index_errors: true 添加到 has_many 关联就可以了。

这会导致以这种方式生成错误,在我的用例中:{:"posts[0].name"=>["must be present"]}