Мои текущие проблемы можно суммировать в заголовке: я использую вложенные атрибуты, но каждый раз, когда я редактирую все это, мои вложенные модели не обновляются, они «клонируются». Позвольте привести пример. позволяет нам иметь вложенные модели, у которых есть строковый столбец, и сейчас его значение равно «A». мы решили, что хотим, чтобы он был «B», и нажмите «Обновить». мы получаем две модели: одну с «А», а другую с «В». Затем мы снова меняем «A» на B. мы получаем «A», «B», «B», «B». Каждый раз, когда я пытаюсь обновить, у меня есть еще 2 модели. это отстой. (чтобы сделать его более понятным, я могу сказать, что удвоенные поля - это то, что я хочу) Я определил, что это как-то ошибка assign_attributes() & save!
или update_attributes!()
методов, но я знаю, что с accepts_nested_attributes_for
он не должен так работать. Вот необходимый код:Вложенные атрибуты удваиваются при обновлении
Плакаты контроллер (Poster является модель, которая имеет те связанные модели с ним)
def edit
PosterCreator.new(@poster)
end
def update
respond_to do |format|
if @poster.update_attributes(poster_params)
format.html { redirect_to @poster }
else
format.html { render action: "new" }
end
end
end
def poster_params
params.require(:poster).permit(:content, :title, :category_id, string_fields_attributes: [:detail, :field_id], float_fields_attributes: [:float_number, :field_id], integer_fields_attributes: [:integer_number, :field_id], text_fields_attributes: [:description, :field_id], date_fields_attributes: [:date, :field_id])
end
Вот PosterCreator беспокойство я использую в «редактировать» действие
class PosterCreator
attr_accessor :poster
def initialize(poster)
@poster = poster
build_fields_based_on_category
end
private
def build_fields_based_on_category
@poster.category.fields.each do |field|
unless list_all_field_ids.include?(field.id)
@custom_field = @poster.send("#{field.kind}_fields").build
@custom_field.source = field
##########little explanation. Field model has kind, which can be integer, text, date etc, based on it, proper fields for poster are built
end
end
end
def list_all_field_ids
@poster.list_fields.map do |field|
field.field_id
end
end
end
И, наконец, Класс плаката:
class Poster < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_many :text_fields
has_many :string_fields
has_many :integer_fields
has_many :float_fields
has_many :date_fields
accepts_nested_attributes_for :float_fields
accepts_nested_attributes_for :integer_fields
accepts_nested_attributes_for :text_fields
accepts_nested_attributes_for :string_fields
accepts_nested_attributes_for :date_fields
def list_fields
fields = []
self.text_fields.each { |field| fields << field }
self.string_fields.each { |field| fields << field }
self.integer_fields.each { |field| fields << field }
self.date_fields.each { |field| fields << field }
self.float_fields.each { |field| fields << field }
fields
end
end
Также может понадобиться файл poster_form:
= simple_form_for @poster do |f|
= f.input :category_id, collection: Category.all, prompt: "Choose category"
= f.input :title
= f.input :content
= f.simple_fields_for :string_fields do |fsf|
= fsf.input :detail
= fsf.input :field_id, as: :hidden
= f.simple_fields_for :text_fields do |ftf|
= ftf.input :description
= ftf.input :field_id, as: :hidden
= f.simple_fields_for :integer_fields do |fif|
= fif.input :integer_number
= fif.input :field_id, as: :hidden
= f.simple_fields_for :float_fields do |fff|
= fff.input :float_number
= fff.input :field_id, as: :hidden
= f.simple_fields_for :date_fields do |fdf|
= fdf.input :date
= fdf.input :field_id, as: :hidden
= f.submit
То много кода, но я надеюсь, что кто-то сможет сказать мне, почему он не работает так, как надо
Попробуйте удалить все скрытые: FIELD_ID входы в форме. – jaeheung
Ditto - я не думаю, что вам нужно 'field_id' для каждого' fields_for', Rails должен вводить это автоматически –