我需要知道创建/更新自引用关联记录的更好方法。
我有一个名为Template
的模型,以及与此模型的self-referential
has_many :through
关联:
has_many :related_templates, :foreign_key => :parent_id
has_many :children, :through => :related_templates, :source => :child
has_many :inverse_related_templates, class_name: "RelatedTemplate", :foreign_key => :child_id
has_many :parents, :through => :inverse_related_templates, :source => :parent
这样RelatedTemplates
是一个连接模型。
对于new
表格:
1)填写parent template
详细信息
2)通过在同一表单中创建新模板或将现有模板作为子模板添加到此父模板,添加child templates
。
对于edit
表格:
1)显示parent template
。
2)编辑已分配给它的child template
个详细信息。用户还应该能够edit
已经关联的模板的详细信息。
由于新的和编辑的表单相同。用户还可以在编辑页面中create
新的或add
来自现有的。
我的create
方法是这样的:
def create
Template.transaction do
parent_template = Template.new template_params
if parent_template.save
children_templates = []
# if params of new templates are sent
if params[:template][:children_attributes].present?
new_templates = params[:template][:children_attributes]
new_templates.each do |child|
template = Template.new(attrs)
template.save
children_templates << template
end
end
# if params of existing templates are sent
if params[:template][:existingChildTemplates].present?
existing_ids = params[:template][:existingChildTemplates]
children_templates << Template.where(id: existing_ids)
end
parent_template.children << children_templates
render json: { success: true, template_id: parent_template.id, message: "Created Successfully" }
else
render_422 parent_template, 'Could not save Parent Template.'
end
end
rescue ActiveRecord::RecordInvalid => exception
render json: { success: false, message: "#{exception}" }, status: 500
end
同样,我写的是update
:
def update
if @template.update_attributes template_params
if params[:template][:children_attributes].present?
associated_templates = @template.children
new_templates = params[:template][:children_attributes]
new_templates.each do |child|
unless child[:id].present?
# if new template added
associated_templates.build(attrs)
@template.save
else
# if template attributes updated
new_template_params = child.permit(attrs)
child_template = associated_templates.where(id: child[:id]).first
if (child_template[:name] != child[:name]) || (child_template[:role_id] != child[:role_id])
child_template.update_attributes(new_template_params)
end
end
end
end
if params[:template][:existingChildTemplates].present?
children_templates = []
# if selected from the existing one
existing_ids = params[:template][:existingChildTemplates]
children_templates << Template.where(id: existing_ids)
@template.children << children_templates
end
render json: { success: true, message: 'Updated.' }
else
render_422 @template, 'Template could not be updated.'
end
end
问题
如何列出children_attributes白名单?我在这里手动使用params
。我尝试在permit方法中添加children_attributes: []
,在模型中添加accepts_nested_attributes_for :children
但仍然是Unpermitted Parameter
。
编写create/update
方法的更好方法是什么?我应该如何处理validation
错误?