Поле Rails _destroy появляется дважды в форме
У меня есть две модели, Preset и Plot, как показано ниже:
class Preset < ApplicationRecord
belongs_to :user
has_many :plots, :dependent => :destroy
accepts_nested_attributes_for :plots, allow_destroy: true
end
class Plot < ApplicationRecord
belongs_to :preset
belongs_to :theme, optional: true
end
И вложенная форма для редактирования пресетов:
= form_with(model: @preset, local: true, method: "patch") do |f|
= label_tag(:preset_name, "Preset name:")
= text_field_tag(:preset_name, @preset.name)
%br
= f.fields_for :plots do |builder|
%br
= render 'editplot', f: builder
%br
Частичный _editplot, который определяет флажок для уничтожения сюжета согласно railscast 196:
= f.label(:name, "Change plot:")
= f.select(:name, options_for_select([['Existing Plot 1', 'Existing Plot 1'], ['Existing Plot 2', 'Existing Plot 2']]))
= f.label(:_destroy, "Remove plot")
= f.check_box(:_destroy)
Я разрешил параметр _destroy в контроллере пресетов
def preset_params
params.require(:preset).permit(:name, plots_attributes: [:id, :name, :parameter_path, :theme_id, :_destroy])
end
Все остальные аспекты редактирования предустановок работают нормально, но флажок для _destroy - нет. Параметры уничтожения одного из двух графиков на экране редактирования отображаются в консоли следующим образом:
Parameters: {"authenticity_token"=>"TOKEN", "preset_name"=>"Preset", "preset"=>{"plots_attributes"=>{"0"=>{"name"=>"Existing Plot 1", "_destroy"=>"1", "id"=>"16"}, "1"=>{"name"=>"Existing Plot 1", "_destroy"=>"0", "id"=>"17"}}}, "commit"=>"Update Preset", "id"=>"25"}
Наличие "_destroy"=>"1" предполагает, что это работает как задумано. Однако при просмотре страницы с помощью инструментов Chrome Dev обнаруживается также скрытое поле.<input name="preset[plots_attributes][0][_destroy]" type="hidden" value="0">
рядом с флажком, значение _destroy которого 0 также передается при отправке формы. У меня такое ощущение, что этот элемент мешает форме, но я не уверен, откуда он взялся и как от него избавиться.
Я не включил его здесь, но у меня есть некоторый JS-код в той же форме, который добавляет и удаляет частичные элементы "нового сюжета", и они генерируют свои собственные поля _destroy. Я не думал, что они могут быть причиной проблемы, но при необходимости могу добавить этот код для редактирования.
2 ответа
Проблема заключалась не в флажке, как указал zwippie, а в моем контроллере. Я пытался обновить атрибуты предустановки и графиков вручную в контроллере (т.е. используя строки вроде@plot.update(name: plot_name, parameter_path: _parameter_path)
). Поскольку я делал это вручную, я фактически не обрабатывал параметр _destroy, и поэтому rails ничего не делал с ним после того, как он был передан из формы.
Чтобы исправить это, я использовал @preset.update(preset_params)
вместо этого, где preset_params
представляет разрешенные параметры в контроллере. Пока _destroy разрешен, он удаляет объект.
def preset_params
params.require(:preset).permit(:name, plots_attributes: [:id, :name, :parameter_path, :theme_id, :_destroy])
end
Это поведение Rails по умолчанию, как описано на странице документации по флажкам.