我目前的问题可以在标题中总结:我使用嵌套属性,但每次编辑整个内容时,我的嵌套模型都不会更新,它们会被克隆“#”;让我给你举个例子。让我们拥有具有字符串列的嵌套模型,现在它的值是" A"。
我们决定我们希望它是" B",然后点击更新。我们得到的是两个模型,一个用" A",另一个用" B"。然后我们改变" A"再次进入B.我们得到了" A"," B"," B"," B"。每次我尝试更新,我有2倍的模型。它很糟糕。(为了让它更清楚,我可以说双倍的字段是我想要的那个)
我已经确定它是某种assign_attributes() & save!
或update_attributes!()
方法的错误,但我知道accepts_nested_attributes_for
它不应该像那样工作。这是必要的代码:
海报控制器(海报是与之相关的模型的模型)
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
这是很多代码,但我希望有人能够告诉我它为什么不按照应该的方式工作
答案 0 :(得分:0)
您需要在海报控制器中为每个嵌套模型添加两个内容:id和:_destroy,即:string_fields_attributes: [:id, :detail, :field_id, :_destroy]
。
您需要为所有嵌套模型添加这些字段。 这将允许您的控制器识别是否对已经存在的模型进行了更改(因此不会创建新模型),并且它使posters_controller能够销毁记录。
您还需要在poster.rb
中添加accepts_nested_attributes_for :string_fields, allow_destroy: true