Rails сохраняют неудачные проверки с вложенными атрибутами - PullRequest
0 голосов
/ 16 марта 2019

user.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

seed.rb

user = User.find_or_initialize_by(email: "barry@websmash.com")
user.characters_attributes = [{ name: "Barry", username: "barry" }]
user.save!

Я пытаюсь настроить свой файл seed.rb, используя find_or_initialize_by, чтобы я мог запустить rails db:seed всякий раз, когда я хочу добавить атрибуты в записи.Но выполнение rails db:seed выдает эту ошибку:

Проверка не удалась: символы Имя пользователя уже занято

Как получить проверки, работающие через вложенные атрибуты?

Ответы [ 2 ]

1 голос
/ 16 марта 2019

Проблема 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 %>

Это, конечно, можно очистить, создав общий партиал для сообщений об ошибках.

0 голосов
/ 16 марта 2019

Здесь accepts_nested_attributes_for делает то, что вы пытаетесь достичь, имея хук после сохранения. Итак, что здесь происходит, так это то, что, когда вы пытаетесь сохранить вашего пользователя с символьными атрибутами, по умолчанию (потому что вы принимаете_nested_attributes_for) оба объекта сохраняются. Затем у вас также есть хук после сохранения для создания ваших символов, который пытается создать символы снова, следовательно, выдает уникальную ошибку проверки ограничения. Вам не понадобится ваш крюк after_save здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...