如何创建复杂的嵌套 - >属于对象?

Sha*_*non 7 ruby ruby-on-rails

我正在构建一个表单,用户应该可以使用字段创建模板.不过,他们也应该能够创建可选Collection其中belongs_to每个Field在同一时间.

到目前为止它看起来像这样:

templates: id, name
template_fields: id, template_id, collection_id, field_name
collections: id, name
collection_values: id, collection_id, value
Run Code Online (Sandbox Code Playgroud)

楷模

模板

class Template < ActiveRecord::Base
  has_many :template_fields
  accepts_nested_attributes_for :template_fields
end
Run Code Online (Sandbox Code Playgroud)

模板字段

class TemplateField < ActiveRecord::Base
  belongs_to :template
  belongs_to :collection
end
Run Code Online (Sandbox Code Playgroud)

采集

class Collection < ActiveRecord::Base
  has_many :collection_values
end
Run Code Online (Sandbox Code Playgroud)

CollectionValue

class CollectionValue < ActiveRecord::Base
  belongs_to :collection
end
Run Code Online (Sandbox Code Playgroud)

我该如何创建这些对象?我如何在控制器中进行此操作?

我能想到的唯一方法是将其创建为嵌套关联(即使Collection不是真正的嵌套属性),也可以在模板之前创建集合,并以某种方式将每个Field链接到创建的每个Collection.

调节器

def create
  @template = Template.new(template_params)
  if @template.save
    flash[:notice] = "Template successfully created."
    flash[:color]= "valid"
    redirect_to templates_path
  else
    flash[:notice] = "Form is invalid"
    flash[:color]= "invalid"
    render :new
  end
end

def template_params
  params.require(:template).permit(:id,:name, template_fields_attributes: [:id, :template_id, :field_name, :collection_id, collection_values_attributes: [:value] ])
end
Run Code Online (Sandbox Code Playgroud)

use*_*754 5

我认为你需要这些类型的关系添加到您的模型has_many :through,并has_one :through以涉及collectioncollection_valuestemplate,然后修改template.rb包括:

has_one :collection, through: :template_fields
Run Code Online (Sandbox Code Playgroud)

上面的行假定一个模板只有一个集合

has_many :collection_values, through: :collection
accepts_nested_attributes_for :template_fields, :collection, :collection_values
Run Code Online (Sandbox Code Playgroud)

您还需要修改template_params控制器中的包含collection_attributescollection_values_attributes

有关更详细的实现,您的template_model样子将如下所示

模板

class Template < ActiveRecord::Base
  has_many :template_fields
  has_many :collections, through: :template_fields
  has_many :collection_values, through: :collection
  accepts_nested_attributes_for :template_fields, :collections, :collection_values
end
Run Code Online (Sandbox Code Playgroud)


Dmi*_*nik 4

对于给定的要求,您可能有:

class CollectionValue < ActiveRecord::Base
  belongs_to :collection
end

class Collection < ActiveRecord::Base
  has_many :collection_values
  accepts_nested_attributes_for :collection_values
end

class TemplateField < ActiveRecord::Base
  belongs_to :template
  belongs_to :collection
  accepts_nested_attributes_for :collection
end

class Template < ActiveRecord::Base
  has_many :template_fields
  accepts_nested_attributes_for :template_fields
end
Run Code Online (Sandbox Code Playgroud)

这将使以下代码工作:

Template.create name: 'template_name',
  template_fields_attributes: [
    {name: 'field_name', collection_attributes:
      {name: 'collection_name', collection_values_attributes: [
        {name: 'col_value_1'},
        {name: 'col_value_2'}
      ]}
    }
  ]
Run Code Online (Sandbox Code Playgroud)

您可以在 Rails 控制台中尝试一下。此示例将创建所有记录,因为它不包含任何 ID。它会以同样的方式工作TemplateController#create

您最好阅读并理解accepts_nested_attributes_for