Rails Model - Создание с использованием шаблона - PullRequest
0 голосов
/ 12 сентября 2018

В моем приложении у меня есть возможность создавать «уроки», и каждый урок содержит несколько «компонентов».Прямо сейчас я пытаюсь реализовать возможность создания урока из шаблона, чтобы он дублировал / воссоздал компоненты из шаблона для нового урока.

Структура данных моего 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.Как я могу пересмотреть свою модель, чтобы убедиться, что компоненты созданы правильно?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Моя идея - внешний цикл, который дублирует разделы. новый идентификатор секции используется при воссоздании других компонентов (итоги и вопросы) во внутреннем цикле, что будет обновлять и корректировать ассоциации.

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

Вероятно, стоит обновить ваш вопросупомянуть, что вы используете самостоятельное ссылочное наследование одной таблицы или как этот метод называется.Это не то, что я видел очень часто.

0 голосов
/ 12 сентября 2018

Создайте поверхностную копию объекта 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

#dup

Дублированные объекты имеют идентификатор не назначен и обрабатываются как новые записи.Обратите внимание, что это «мелкая» копия, поскольку она копирует только атрибуты объекта, а не его ассоциации.Степень «глубокой» копии зависит от приложения и, следовательно, предоставляется приложению для реализации в соответствии с его потребностями.Метод dup не сохраняет метки времени (создано | обновлено) _ (при | вкл.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...