#ruby-on-rails
Вопрос:
Класс shop
accepts_nested_attributes_for :shopzones, allow_destroy: true
в то время как shops_controller определяет действие и пытается определить сильные параметры
def shopzone
@shopzone = Shopzone.new
@shopzone.save
end
def shopzone_params # in addition to the def shop_params method
params.require(:shopzone).permit(:shop_id, :name, :sequence, :area)
end
Форма
<%= form_with url: shopzone_shop_path(id: @shop.id) do |f| %>
<%= f.hidden_field 'shopzone[shop_id]', value: @shop.id %>
<div class='grid-x grid-padding-x'>
<div class='cell small-3 alert'>
<%= t('name') %>
<%= f.text_field 'shopzone[name]' %>
<%= t('sequence') %>:
<%= f.number_field 'shopzone[sequence]' %>
</div>
</div>
<div class='grid-x grid-padding-x'>
<div class='cell small-12 text-center'>
<%= f.submit t('create'), class: 'button' %>
</div>
</div>
<% end %>
Но он отображается не data-remote="true"
так, как ожидается по умолчанию.
<form action="/shops/3/shopzone" accept-charset="UTF-8" method="post">
При отправке параметры регистрируются, но в соответствии с ожидаемым HTML-ответом
Processing by ShopsController#shopzone as HTML
Parameters: {"authenticity_token"=>"[FILTERED]", "shopzone"=>{"shop_id"=>"3", "name"=>"central", "sequence"=>"1"
Если форма изменена на
<%= form_with(url: shopzone_shop_path(id: @shop.id), local: false) do |f| %>
затем данные удаленно отображаются
<form action="/shops/3/shopzone" accept-charset="UTF-8" data-remote="true" method="post">
Однако ответ сервера по-прежнему ожидает обработки HTML
Processing by ShopsController#shopzone as HTML
[...]
ActionController::UnknownFormat (ShopsController#shopzone is missing a template for this request format and variant.
request.formats: ["text/html"]
Таким образом, первая странность заключается в том, что предполагаемое поведение rails по умолчанию не срабатывает?
Если к действию controlelr добавляется
respond_to do |format|
format.js
end
Процесс выполняется
Started POST "/shops/3/shopzone" for ::1 at 2021-06-11 10:34:28 0200
Processing by ShopsController#shopzone as JS
Parameters: {"authenticity_token"=>"[FILTERED]", "shopzone"=>{"shop_id"=>"3", "name"=>"central", "sequence"=>"1" [...]
но затем жалуется на проверки, которые существуют в модели
ActiveRecord::RecordInvalid (Validation failed: Shop must exist, Sequence can't be blank, Name can't be blank):
что противоречит представленным параметрам. Проверка параметров в действии перед сохранением puts @shopzone.inspect
эффективно возвращает нулевые параметры.
Таким образом, что-то во вложенных атрибутах отбрасывает поведение по умолчанию.
Как лучше всего обработать запрос как ненавязчивый JS ?
Комментарии:
1. Это не похоже на правильное использование вложенных параметров. объектом вашей формы должен быть магазин, и он должен использовать fields_for для вложенной зоны магазина. В противном случае просто удалите вложенные параметры, так как на самом деле вы их не используете
2. Да, я пошел по этому пути. Однако у него был ряд проблем, и в итоге все оказалось не так просто. С парами есть прямой путь
Shopzone.create!
вперед. Увы, они сами по себе не являются «сильными».3. По крайней мере, переместите эту функциональность в контроллер shopzone, тогда ему не имеет смысла проходить через магазины. ваша форма, похоже, ничего не меняет в магазине, так почему же она переходит в shops_controller? и удалите атрибуты nested_attributes, если вы пойдете по этому маршруту.
4. Нет необходимости в контроллере как таковом; попытка обработать класс только с помощью определения модели.
Ответ №1:
Я сошлюсь на часть вашего вопроса, так как вы поднимаете пару вопросов:
Поскольку Rails 6.1 form_with по умолчанию не является ajax, поэтому, чтобы сделать его ajax, вам необходимо передать local: false
или установить параметр глобальной конфигурации ( config.action_view.form_with_generates_remote_forms
) в значение true.
Сравните форму с документацией Rails 5.2 .
:локально — По умолчанию отправленные формы являются удаленными и ненавязчивыми XHRS. Отключите удаленную отправку с помощью local: true.
:локальная — По умолчанию форма отправляется через типичные HTTP-запросы. Включите удаленную и ненавязчивую отправку XHRs с помощью local: false. Удаленные формы могут быть включены по умолчанию, установив config.action_view.form_with_generates_remote_forms = true
Еще одна вещь, которую я вижу, это то, что вы ничего не делаете с параметрами shopzone, но даже если это сработает, пересмотрите то, как вы это создали, это не стандартное использование вложенных атрибутов.
def shopzone
@shopzone = Shopzone.new(shopzone_params) # you forgot this!
@shopzone.save
end
def shopzone_params # in addition to the def shop_params method
params.require(:shopzone).permit(:shop_id, :name, :sequence, :area)
end
Комментарии:
1.
shopzone_params
необходимо было настроить для правильного выполнения действия, что объясняет нулевые параметры при их проверке.