Ошибки проверки исчезают после рендеринга ‘new’

#ruby-on-rails #ruby-on-rails-6

#ruby-on-rails #ruby-on-rails-6

Вопрос:

У меня есть вложенная форма, которая фиксирует информацию для двух моделей, игр и команд.

Мои модели:

 class Game < ApplicationRecord
    has_many :teams
    accepts_nested_attributes_for :teams
    validates_associated :teams
    validates :start_time, presence: true
end

class Team < ApplicationRecord
    belongs_to :game
    validates :name,  presence: true, length: { maximum: 50 }
end
  

Перед сохранением записей необходимо пройти проверку. Если сохранить не удается, форма должна быть повторно отображена, а сообщения об ошибках проверки отображаются в соответствии с контроллером ниже. Однако сообщения об ошибках никогда не отображаются.

Мой GamesController:

 class GamesController < ApplicationController

    def new
        @game = Game.new
        @team = @game.teams.build
    end

    def create  
        @game = Game.new(game_params)

        unless @game.save
            render 'new'
            return
        end

        # Some other code that shouldn't run if the save fails, hence the 'return' above
        
    end
end
  

Моя форма (new.html.erb):

 <%= render 'shared/error_messages' %> 

<%= form_with model: @game do |f| %>
<%= f.fields_for :teams do |f_teams| %>

<%= f_teams.label :name %>
<%= f_teams.text_field :name, class: 'form-control'%>

<%= f.label :start_time, "Game day" %>
<%= f.date_field :start_time, id: "game_day", class: 'form-control' %>

<%= f.submit "Book now!", class: "btn btn-primary" %>

<% end %>
<% end %>
  

и, наконец, частичное сообщение об ошибке:

 <% if @game.errors.any? %>
<div id="error_explanation">
    <div class="alert alertdanger">
        The form contains <%= pluralize(@game.errors.count, "error") %>.
    </div>
    <ul>
        <% @game.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
        <% end %>
    </ul>
</div>
<% end %>
  

Когда я намеренно отключаю проверки (например, не включая игровой день), частичное сообщение об ошибке не запускается, предположительно, из-за @game.errors.any?равно false.

Если я использую byebug или если я перехожу через консоль rails, я получаю ошибки проверки, например, start_time не может быть пустым.

Чего мне здесь не хватает?

Редактировать

Решение Криса, приведенное ниже, сработало для меня. Однако я хотел, чтобы мой контроллер запускал JS, если проверки были выполнены и сохранение прошло успешно. Итак, я вернулся и удалил предложенное local: true и разрешил удаленную отправку. Что я сделал, чтобы исправить проблему, так это рендеринг html, если сохранить не удалось:

 unless @game.save
    respond_to do |format|
        format.html {   render 'new' }
    end
    return
end
  

Это не сработало из коробки, потому что turbolinks мешает. Поэтому я закончил тем, что добавил gem 'turbolinks_render' в свой Gemfile, и вуаля, теперь все работает отлично.

Огромное спасибо Джоэлу (https://joelc.io/ajax-ruby-on-rails-forms ) для пошагового руководства.

Ответ №1:

В вашем новом файле.html.erb попробуйте

 <%= form_with(model: @game, local: true) do |f| %>
  

Некоторая полезная информация для использования form_with тега здесь:
https://medium.com/@tinchorb/form-with-building-html-forms-in-rails-5-1-f30bd60ef52d

Комментарии:

1. Установив local: true, моя форма больше не отправляется удаленно (так написано на tin, я понимаю!), Но я считаю, что это имеет некоторые негативные последствия для моего приложения, например, мой файл js.erb не загружается в конце действия создания контроллера. Итак, последующий вопрос @chris: Есть ли способ выполнить повторный рендеринг формы с ошибками проверки без использования локальной отправки. Или, альтернативно, есть ли способ запустить файл js.erb после локальной отправки? Спасибо за любые отзывы