Проблема 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 %>
Это, конечно, можно очистить, создав общий партиал для сообщений об ошибках.