The `reload` method added to max_votes validation is needed because the author gets here with some changes because of the around_action `switch_locale`, which adds some changes to the current user record and therefore, the lock method raises an exception when trying to lock it requiring us to save or discard those record changes.
49 lines
1.4 KiB
Ruby
49 lines
1.4 KiB
Ruby
class Poll::Answer < ApplicationRecord
|
|
belongs_to :question, -> { with_hidden }, inverse_of: :answers
|
|
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :poll_answers
|
|
|
|
delegate :poll, :poll_id, to: :question
|
|
|
|
validates :question, presence: true
|
|
validates :author, presence: true
|
|
validates :answer, presence: true
|
|
validate :max_votes
|
|
|
|
validates :answer, inclusion: { in: ->(a) { a.question.possible_answers }},
|
|
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 save_and_record_voter_participation
|
|
transaction do
|
|
touch if persisted?
|
|
save!
|
|
Poll::Voter.find_or_create_by!(user: author, poll: poll, origin: "web")
|
|
end
|
|
end
|
|
|
|
def destroy_and_remove_voter_participation
|
|
transaction do
|
|
destroy!
|
|
|
|
if author.poll_answers.where(question_id: poll.question_ids).none?
|
|
Poll::Voter.find_by(user: author, poll: poll, origin: "web").destroy!
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def max_votes
|
|
return if !question || question&.unique? || persisted?
|
|
|
|
author.reload
|
|
author.lock!
|
|
|
|
if question.answers.by_author(author).count >= question.max_votes
|
|
errors.add(:answer, "Maximum number of votes per user exceeded")
|
|
end
|
|
end
|
|
end
|