In case we receive consecutive requests we are locking the poll author record until the first request transaction ends, so the author answers count during subsequent requests validations is up to date.
38 lines
1.1 KiB
Ruby
38 lines
1.1 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
|
|
|
|
private
|
|
|
|
def max_votes
|
|
return if !question || question&.unique? || persisted?
|
|
|
|
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
|