Skip to content

Instantly share code, notes, and snippets.

@marekkirejczyk
Created December 14, 2011 11:07
Show Gist options
  • Save marekkirejczyk/1476151 to your computer and use it in GitHub Desktop.
Save marekkirejczyk/1476151 to your computer and use it in GitHub Desktop.
Some model
class OpenQuestionnaire::Group < ActiveRecord::Base
set_table_name :open_questionnaire_groups
belongs_to :open_questionnaire, :class_name => 'OpenQuestionnaire::Base'
has_many :questions, :dependent => :destroy, :order => :position
has_many :condition_questions, :class_name => 'OpenQuestionnaire::Question::ItemQuestion::Condition'
acts_as_list :scope => :open_questionnaire
validates_presence_of :name, :unless => Proc.new {|group| group.new_record? }
validates_uniqueness_of :name, :scope => :open_questionnaire_id
before_destroy :last_left?
before_create :set_names_sequence
def self.default_name
I18n.t 'pages.library.open_questionnaires.groups.default_name'
end
def next_groups
OpenQuestionnaire::Group.where(
'position > ? and open_questionnaire_id = ?', self.position, self.open_questionnaire_id
).order :position
end
def set_names_sequence
self.name ||= self.class.default_name
self.name = self.next_name until self.valid?
end
def is_target_of_condition_question?
!OpenQuestionnaire::Question::Item.where(:next_group_id => self.id).blank?
end
def next
if self.next_group_id
self.open_questionnaire.groups.find_by_id self.next_group_id
else
self.open_questionnaire.groups.where(:position => self.position.next).first
end
end
def next_with_pages
group = self.next
group and group.pages.empty? ? group.next_with_pages : group
end
def self.next_page_for(current_group_id, current_page_index)
current_group = self.find_by_id current_group_id
# Get first group with pages
group = (current_group and current_group.pages.empty?) ? current_group.next_with_pages : current_group
if group
pages = group.pages
if current_page_index and (current_page_index < pages.count - 1)
pages[current_page_index + 1]
elsif current_page_index
if next_group = group.next_with_pages
next_group.pages.first
end
else
pages.first
end
end
end
def pages
pages_array = self.questions.split {|element| element.is_a? OpenQuestionnaire::Question::PageBreak }
pages_array.reject {|element| element.empty? }
end
def check_consistency_after_group_reorder
self.check_group_consistency
self.check_condition_question_consistency
end
def check_consistency_after_group_destroy
self.check_group_consistency_after_destroy
self.check_condition_question_consistency_after_destroy
end
def check_condition_question_consistency(type = 'after_reload')
self.condition_questions.each do |question|
question.items.each do |item|
next if item.next_group.blank?
if type.eql? 'after_reload'
if item.next_group.position >= question.group.position
item.update_attribute :next_group_id, nil
end
elsif type.eql? 'after_destroy'
if item.next_group.position == self.position
item.update_attribute :next_group_id, nil
end
end
end
end
end
def check_group_consistency(type = 'after_reload')
self.open_questionnaire.groups.each do |group|
next if group.next.blank?
if type.eql? 'after_reload'
if group.position >= group.next.position
group.update_attribute :next_group_id, nil
end
elsif type.eql? 'after_destroy'
if group.next.position == self.position
group.update_attribute :next_group_id, nil
end
end
end
end
def last_left?
if self.open_questionnaire_groups_count == 1
self.errors.add :base, I18n.t('activerecord.errors.open_questionnaire.group.can_not_remove_the_last_group')
false
end
end
def open_questionnaire_groups_count
OpenQuestionnaire::Group.where(:open_questionnaire_id => self.open_questionnaire_id).count
end
protected
def next_name
regex = /\ \d+$/
return self.class.default_name if self.name.blank?
seq = self.name[regex]
return self.name + ' 2' if seq.nil?
self.name.gsub regex, " #{seq.to_i+1}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment