ruby-on-rails - Rails 使用嵌套属性保存失败的验证
问题描述
用户.rb
has_many :characters
accepts_nested_attributes_for :characters
after_save self.characters.create
字符.rb
belongs_to :user
validates :username, presence: true, uniqueness: true
validates :user, presence: true
种子.rb
user = User.find_or_initialize_by(email: "barry@websmash.com")
user.characters_attributes = [{ name: "Barry", username: "barry" }]
user.save!
我正在尝试设置我的seeds.rb 文件,find_or_initialize_by
以便rails db:seed
在我想向记录添加属性时运行。但是运行rails db:seed
给出了这个错误:
验证失败:字符用户名已被占用
如何通过嵌套属性获得验证?
解决方案
问题是after_save self.characters.create
。它不仅完全没有必要,而且会触发验证失败,因为您正在创建没有任何属性的用户记录。
要验证关联记录,请使用以下validates_associated
方法:
class User < ApplicationRecord
has_many :characters
accepts_nested_attributes_for :characters
validates_associated :characters
end
这将遍历关联的记录并添加characters are invalid
到父用户记录上的错误,除非所有字符都有效。
如果要显示每个字符的错误,则必须遍历每个嵌套记录上的错误对象:
<%= form_with(model: user, local: true) do |form| %>
# ...
<fieldset>
<legend>Characters</legend>
<%= form.fields_for(:characters) do |cf| %>
<% cf.object.tap do |character| %>
<% if character.errors.any? %>
<div class="errors">
<h2><%= pluralize(character.errors.count, "error") %> prohibited this character from being saved:</h2>
<ul>
<% character.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% end %>
<div class="character">
<div class="field">
<%= cf.label :username %>
<%= cf.text_field :username %>
</div>
</div>
<% end %>
</fieldset>
# ...
<% end %>
这当然可以通过为错误消息创建通用部分来清除。
推荐阅读
- javascript - 如何替换模板中的所有内容主标签
- android - 如何在 Android 的 Realm Migration 上的新类上添加现有对象
- excel - Excel,如何将显示为常量的文本字符串更改为真正的公式?
- python - 使用 memory_profiler 分析代码会增加执行时间
- r - 重新排序堆叠的 geom_bar
- php - 多对多数据库架构
- jquery - 如何使用 JQuery 3.3.1 和 Bootstrap 3.3.7 设置日期选择器?
- c# - f# 和 c# 得到不同的基本数学答案
- corda - 重新启动 Corda 节点结果发现多个具有合法名称的节点
- kotlin - 如何计算 Kotlin 中的替换次数?