Skip to content

Instantly share code, notes, and snippets.

@tchak
Created February 1, 2021 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tchak/d842ef95b6ab02f8a792e97fabc0d84c to your computer and use it in GitHub Desktop.
Save tchak/d842ef95b6ab02f8a792e97fabc0d84c to your computer and use it in GitHub Desktop.
class Survey < ApplicationRecord
has_many :revisions
belongs_to :draft_revision
belongs_to :published_revision
has_many :draft_fields, through: :draft_revision
has_many :fields, through: :published_revision
def publish
self.published_revision = draft_revision
self.draft_revision = draft_revision.clone
end
end
class SurveyRevision < ApplicationRecord
belongs_to :survey
has_many :field_positions, -> { ordered }
has_many :fields, through: :field_positions
def clone(revision)
new_revision = survey.revisions.create
revision.field_positions.each do |field_position|
new_revision.field_positions.create(
field: field_position.field,
position: field_position.position
)
end
new_revision
end
def add_field(label:)
ensure_draft
field = SurveyField.create(revision: self, label: label)
field_positions.create(field: field, position: field_positions.size)
end
def update_field(field, label:)
ensure_draft
if field.revision == self
field.update(label: label)
else
cloned_field = SurveyField.create(revision: self, label: field.label)
field_positions.where(field: field).update(field: cloned_field)
end
end
def remove_field(field)
ensure_draft
if field.revision == self
field.destroy
else
field_positions.delete(field)
end
end
def draft?
survey.draft_revision == self
end
def ensure_draft
raise "only draft can be edited" unless draft?
end
end
class SurveyField < ApplicationRecord
belongs_to :revison
has_many :field_positions
end
class FieldPosition < ApplicationRecord
belongs_to :revision
belongs_to :field
scope :ordered, -> { order(:position) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment