Как удалить дочерний элемент во время обновления с параметром reject_if для accepts_nested_attributes_for
Я на Rails 5.0. Я не совсем уверен, должно ли это сработать или мне нужен другой подход. У меня есть модели для процедуры и усложнения, где процедура has_many Сложности определены так;
class Procedure < ActiveRecord::Base
has_many :complications, dependent: :destroy
accepts_nested_attributes_for :complications, allow_destroy: true, reject_if: proc{|attr| attr[:name] == 'None'}
end
class Complication < ActiveRecord::Base
belongs_to :procedure
validates :name, presence: true
end
Пользователю предоставляется вложенная форма для процедуры с несколькими осложнениями. Я использовал камень кокона, чтобы сделать это динамически. В новой записи пользователю предоставляется пустое поле выбора сложности. Если они оставляют это пустым, проверка не проходит. Это заставляет их выбирать "Нет", чтобы не пропускать поле. Если они выберут "Нет", то не будет никаких осложнений из-за reject_if
вариант. Все это работает точно так, как ожидалось.
У меня возникает проблема, если выбрано осложнение (например, "Ошибка") и запись процедуры впоследствии редактируется. Если сложность изменена на "Нет", а затем запись обновлена, сложность останется неизменной (т.е. все еще "Сбой"), когда я хочу, чтобы сложность была уничтожена.
Предположительно опция reject_if не предназначена для удаления записи об обновлении, если она уже существует. Это правильно? Если да, то каков подход к моему делу?
ТИА.
1 ответ
То, что вы хотите, отчасти выходит за рамки reject_if
вариант.
Вы должны быть в состоянии получить функциональность, изменяя добавленные в белый список параметры, чтобы добавить _destroy = '1'
если имя "Нет" (или пусто, или ноль).
class ProceeduresController
# ...
def update
end
private
# ...
# Only allow a trusted parameter "white list" through.
def proceedure_params
params.require(:proceedure)
.permit(:name,complications_attributes: [:id, :name, :_destroy])
end
def update_params
proceedure_params.tap do |p|
p["complications_attributes"].each do |a|
if a[:id].present? && ["None", nil, ""].includes?(a[:name])
a[:_destroy] = '1'
end
end
end
end
end
class Procedure < ActiveRecord::Base
has_many :complications, dependent: :destroy
accepts_nested_attributes_for :complications,
allow_destroy: true,
reject_if: :reject_attributes_for_complication?
def self.reject_attributes_for_complication?
return false if attr[:_destroy]
attr[:name] == 'None'
end
end