在我的应用程序中,我可以创建“课程”,并且每个课程都包含多个“组件”。现在,我正在尝试实现从模板创建课程的功能,以便它将模板中的组件复制/重新创建到新课程。
我的component
的数据结构是这样的:
{
id: 123,
type: Section,
content: "abc",
section_id: null
},
{
id: 124,
type: Question,
content: "abc?",
section_id: 123
},
{
id: 125,
type: Section,
content: "defg",
section_id: null
},
{
id: 126,
type: Outcome,
content: "defg?",
section_id: 125
},
所需结果:
{
id: 993,
type: Section,
content: "abc",
section_id: null
},
{
id: 994,
type: Question,
content: "abc?",
section_id: 993
},
{
id: 995,
type: Section,
content: "defg",
section_id: null
},
{
id: 996,
type: Outcome,
content: "defg?",
section_id: 995
},
您会发现Question
/ Outcome
与Section
到section_id
之间存在关联。
在我的课程模型中,我遍历了模板的组件,并为新创建的课程组件获取了它们的属性。
class Lesson
attr_accessor :lesson_template_id
# == Callbacks ==============================
after_create :create_template_components, if: :lesson_template_id_present?
def lesson_template
if @lesson_template_id != ''
LessonTemplate.find(@lesson_template_id)
else
nil
end
end
private
def lesson_template_id_present?
!!@lesson_template_id
end
def create_template_components
if lesson_template
lesson_template.components.each do |c|
self.components.create!({
type: c.type,
content: c.content,
section_id: c.section_id
})
end
end
end
但是问题是section_id
是不正确的,因为新创建的节将具有新的/不同的id
。如何修改模型以确保正确创建组件?
答案 0 :(得分:1)
创建Section
对象的浅表副本,然后创建它并将其附加到新组件上。
def create_template_components
if lesson_template
lesson_template.components.each do |c|
newSection = if c.type == 'Question'
c.section && c.section.dup
else
nil
end
newSection.save if newSection
self.components.create!({
type: c.type,
content: c.content,
section_id: newSection.try(:id)
})
end
end
end
重复对象没有未分配ID ,并被视为新记录。注意 这是一个“浅”副本,因为它复制了对象的属性 仅,而不是其关联。 “深层”副本的范围是应用程序 具体的,因此留给应用程序来实施 根据其需要。 dup方法不保留时间戳 (创建|更新)_(在|开)。
答案 1 :(得分:1)
我的想法是复制部分的外部循环。在内部循环中重新创建其他组件(结果和问题)时,会使用 new 部分ID,这将使关联保持更新和正确。
lesson_template.sections.each do |old_section|
# outer loop: recreate section
new_section = self.sections.create!({
content: old_section.content
})
old_section.components.each do |old_non_section_component|
# inner loop: recreate all components belonging to section
self.component.create!({
type: old_non_section_component.type,
content: old_non_section_component.content,
# use id from newly-created section, keeping correct association
section_id: new_section.id # <-- IMPORTANT
})
end
end
可能值得更新您的问题,以提及您正在使用自引用单表继承或这种技术的名称。这不是我经常看到的东西。