Add Model changes to work with votation_types
This commit is contained in:
34
app/models/poll/pair_answer.rb
Normal file
34
app/models/poll/pair_answer.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class Poll::PairAnswer < ApplicationRecord
|
||||
|
||||
belongs_to :question, -> { with_hidden }
|
||||
belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id"
|
||||
belongs_to :answer_right, class_name: "Poll::Question::Answer", foreign_key: "answer_rigth_id"
|
||||
belongs_to :answer_left, class_name: "Poll::Question::Answer", foreign_key: "answer_left_id"
|
||||
|
||||
delegate :poll, :poll_id, to: :question
|
||||
|
||||
validates :question, presence: true
|
||||
validates :author, presence: true
|
||||
validates :answer_left, presence: true
|
||||
validates :answer_right, presence: true
|
||||
|
||||
validates :answer_left, inclusion: { in: ->(a) { a.question.question_answers.visibles }},
|
||||
unless: ->(a) { a.question.blank? }
|
||||
|
||||
validates :answer_right, inclusion: { in: ->(a) { a.question.question_answers.visibles }},
|
||||
unless: ->(a) { a.question.blank? }
|
||||
|
||||
|
||||
scope :by_author, ->(author_id) { where(author_id: author_id) }
|
||||
scope :by_question, ->(question_id) { where(question_id: question_id) }
|
||||
|
||||
def self.generate_pair(question, user)
|
||||
answers = question.question_answers.visibles.sample(2)
|
||||
question.pair_answers.by_author(user).map(&:destroy)
|
||||
question.pair_answers.create(author: user, answer_left: answers[0], answer_right: answers[1])
|
||||
end
|
||||
|
||||
def answers
|
||||
[answer_left, answer_right].compact
|
||||
end
|
||||
end
|
||||
@@ -11,6 +11,7 @@ class Poll::PartialResult < ApplicationRecord
|
||||
validates :author, presence: true
|
||||
validates :answer, presence: true
|
||||
validates :answer, inclusion: { in: ->(a) { a.question.question_answers
|
||||
.visibles
|
||||
.joins(:translations)
|
||||
.pluck("poll_question_answer_translations.title") }},
|
||||
unless: ->(a) { a.question.blank? }
|
||||
|
||||
@@ -15,14 +15,22 @@ class Poll::Question < ApplicationRecord
|
||||
has_many :answers, class_name: "Poll::Answer"
|
||||
has_many :question_answers, -> { order "given_order asc" }, class_name: "Poll::Question::Answer", dependent: :destroy
|
||||
has_many :partial_results
|
||||
has_many :pair_answers, class_name: "Poll::PairAnswer"
|
||||
has_one :votation_type, as: :questionable
|
||||
belongs_to :proposal
|
||||
|
||||
attr_accessor :enum_type, :max_votes, :prioritization_type
|
||||
|
||||
validates_translation :title, presence: true, length: { minimum: 4 }
|
||||
validates :author, presence: true
|
||||
validates :poll_id, presence: true, if: Proc.new { |question| question.poll.nil? }
|
||||
|
||||
validates_associated :votation_type
|
||||
accepts_nested_attributes_for :question_answers, reject_if: :all_blank, allow_destroy: true
|
||||
|
||||
delegate :enum_type, :max_votes, :prioritization_type, :max_groups_answers,
|
||||
to: :votation_type, allow_nil: true
|
||||
|
||||
scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) }
|
||||
|
||||
scope :sort_for_list, -> { order("poll_questions.proposal_id IS NULL", :created_at)}
|
||||
@@ -59,10 +67,24 @@ class Poll::Question < ApplicationRecord
|
||||
end
|
||||
|
||||
def answers_total_votes
|
||||
question_answers.inject(0) { |total, question_answer| total + question_answer.total_votes }
|
||||
question_answers.visibles.inject(0) { |total, question_answer| total + question_answer.total_votes }
|
||||
end
|
||||
|
||||
def most_voted_answer_id
|
||||
question_answers.max_by { |answer| answer.total_votes }.id
|
||||
end
|
||||
|
||||
def answers_with_read_more?
|
||||
question_answers.visibles.any? do |answer| answer.description.present? || answer.images.any? ||
|
||||
answer.documents.present? || answer.videos.present?
|
||||
end
|
||||
end
|
||||
|
||||
def user_can_vote(user)
|
||||
max_votes.nil? || max_votes > answers.where(author: user).count
|
||||
end
|
||||
|
||||
def is_positive_negative?
|
||||
votation_type.present? && enum_type == "positive_negative_open"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class Poll::Question::Answer < ApplicationRecord
|
||||
include Galleryable
|
||||
include Documentable
|
||||
paginates_per 10
|
||||
|
||||
translates :title, touch: true
|
||||
translates :description, touch: true
|
||||
@@ -14,6 +15,10 @@ class Poll::Question::Answer < ApplicationRecord
|
||||
validates_translation :title, presence: true
|
||||
validates :given_order, presence: true, uniqueness: { scope: :question_id }
|
||||
|
||||
scope :by_author, -> (author) { where(author: author) }
|
||||
|
||||
scope :visibles, -> { where(hidden: false) }
|
||||
|
||||
def description
|
||||
self[:description].try :html_safe
|
||||
end
|
||||
@@ -29,11 +34,72 @@ class Poll::Question::Answer < ApplicationRecord
|
||||
end
|
||||
|
||||
def total_votes
|
||||
Poll::Answer.where(question_id: question, answer: title).count +
|
||||
::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
|
||||
if !question.votation_type.present?
|
||||
Poll::Answer.where(question_id: question, answer: title).count +
|
||||
::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
|
||||
else
|
||||
case question.votation_type.enum_type
|
||||
when "positive_negative_open"
|
||||
total_votes_positive_negative
|
||||
when "prioritized"
|
||||
total_votes_prioritized
|
||||
when "unique"
|
||||
Poll::Answer.where(question_id: question, answer: title).count +
|
||||
::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
|
||||
else
|
||||
Poll::Answer.where(question_id: question, answer: title).count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def total_votes_positive_negative
|
||||
count_positive_negative(self, true) - count_positive_negative(self, false)
|
||||
end
|
||||
|
||||
def total_votes_prioritized
|
||||
Poll::Answer.where(question_id: question, answer: title).sum(:value)
|
||||
end
|
||||
|
||||
def most_voted?
|
||||
most_voted
|
||||
end
|
||||
|
||||
def total_votes_percentage
|
||||
question.answers_total_votes.zero? ? 0 : (total_votes * 100.0) / question.answers_total_votes
|
||||
end
|
||||
|
||||
def set_most_voted
|
||||
if question.enum_type.nil?
|
||||
for_only_votes
|
||||
else
|
||||
case question.enum_type
|
||||
when "positive_negative_open"
|
||||
answers = question.question_answers.visibles
|
||||
.map { |a| count_positive_negative(a, true) - count_positive_negative(a, false) }
|
||||
is_most_voted = answers.none? {|a| a > total_votes_positive_negative}
|
||||
update(most_voted: is_most_voted)
|
||||
when "prioritized"
|
||||
answers = question.question_answers.visibles
|
||||
.map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).sum(:value) }
|
||||
is_most_voted = answers.none? {|a| a > total_votes_prioritized}
|
||||
update(most_voted: is_most_voted)
|
||||
else
|
||||
for_only_votes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def count_positive_negative(answer, value)
|
||||
Poll::Answer.where(question_id: answer.question, answer: answer.title, positive: value).count
|
||||
end
|
||||
|
||||
def for_only_votes
|
||||
answers = question.question_answers.visibles
|
||||
.map {|a| Poll::Answer.where(question_id: a.question, answer: a.title).count}
|
||||
is_most_voted = answers.none? {|a| a > total_votes}
|
||||
update(most_voted: is_most_voted)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user