#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 после локальной отправки? Спасибо за любые отзывы