Add Model changes to work with votation_types

This commit is contained in:
lalo
2019-05-29 16:51:29 +02:00
committed by Javi Martín
parent c505fd373c
commit 7c9c50f4c6
18 changed files with 745 additions and 3 deletions

View 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

View File

@@ -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? }

View File

@@ -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

View File

@@ -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