Skip to content

Instantly share code, notes, and snippets.

@holman
Created October 31, 2024 21:55
Show Gist options
  • Save holman/2ce9e687a8963dd66f4a31d883ee3405 to your computer and use it in GitHub Desktop.
Save holman/2ce9e687a8963dd66f4a31d883ee3405 to your computer and use it in GitHub Desktop.

Revisions

  1. holman created this gist Oct 31, 2024.
    63 changes: 63 additions & 0 deletions instantiate.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    module Instantiate

    def instantiate(created_by, parent = nil, starting_position = nil, starting_page = 0, root_parent = nil, position = 0)
    attrs = {:created_by => created_by, :position => position + 1,
    :based_on => self, :display_position => nil,
    :root_parent => root_parent, :uncalculated_state => self.state}
    pages_added = 0
    i = if parent.nil?
    Instance.new(attrs)
    else
    parent.children.build(attrs)
    end
    # The first item (the Assessment) needs to be set at position 1 and set the root_parent
    if root_parent.nil?
    pages_added += 1
    root_parent = i
    i.page = 1
    else
    # start on its own page if it is displayable
    if self.displayable?
    pages_added += 1
    i.page = (starting_page + pages_added)
    end
    end

    qs_per_page = i.questions_per_page
    qs_per_page = (qs_per_page == 0 ? 1 : qs_per_page)

    items_created = 1 # this instance is the first item
    nodes_added = 0 # only questions count as displayable nodes
    question_count = 0 # count of consecutive child questions
    max_page = (i.page || starting_page)

    contents_for_instantiation.each do |c|
    if question_count % qs_per_page == 0 and c.kind_of?(Question)
    # start a new page if this is the first question on the page
    pages_added += 1
    question_count = 0
    end

    starting_position ||= 1

    child, child_nodes, child_pages, child_max_page, child_items_created = c.instantiate(created_by, i, starting_position + nodes_added, starting_page + pages_added, root_parent, position + items_created)
    # reset counter if its a section, increment if question
    question_count = child.kind_of?(Section) ? 0 : question_count + 1

    items_created += child_items_created
    nodes_added += child_nodes
    pages_added += child_pages
    max_page = child_max_page
    end
    i.max_page = max_page
    i.question_count = nodes_added

    if i == root_parent
    i.save!
    i.update_attribute(:root_parent, i)
    end

    return i, nodes_added, ((self.kind_of?(Section) and self.displayable?) ? pages_added + 1 : pages_added), ((self.kind_of?(Section) and self.displayable?) ? max_page + 1 : max_page), items_created
    end

    end