vote_validator.rb 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. # frozen_string_literal: true
  2. class VoteValidator < ActiveModel::Validator
  3. def validate(vote)
  4. vote.errors.add(:base, I18n.t('polls.errors.expired')) if vote.poll_expired?
  5. vote.errors.add(:base, I18n.t('polls.errors.invalid_choice')) if invalid_choice?(vote)
  6. vote.errors.add(:base, I18n.t('polls.errors.self_vote')) if self_vote?(vote)
  7. vote.errors.add(:base, I18n.t('polls.errors.already_voted')) if additional_voting_not_allowed?(vote)
  8. end
  9. private
  10. def additional_voting_not_allowed?(vote)
  11. poll_multiple_and_already_voted?(vote) || poll_non_multiple_and_already_voted?(vote)
  12. end
  13. def poll_multiple_and_already_voted?(vote)
  14. vote.poll_multiple? && already_voted_for_same_choice_on_multiple_poll?(vote)
  15. end
  16. def poll_non_multiple_and_already_voted?(vote)
  17. !vote.poll_multiple? && already_voted_on_non_multiple_poll?(vote)
  18. end
  19. def invalid_choice?(vote)
  20. vote.choice.negative? || vote.choice >= vote.poll.options.size
  21. end
  22. def self_vote?(vote)
  23. vote.account_id == vote.poll.account_id
  24. end
  25. def already_voted_for_same_choice_on_multiple_poll?(vote)
  26. if vote.persisted?
  27. account_votes_on_same_poll(vote).where(choice: vote.choice).where.not(poll_votes: { id: vote }).exists?
  28. else
  29. account_votes_on_same_poll(vote).exists?(choice: vote.choice)
  30. end
  31. end
  32. def already_voted_on_non_multiple_poll?(vote)
  33. if vote.persisted?
  34. account_votes_on_same_poll(vote).where.not(poll_votes: { id: vote }).exists?
  35. else
  36. account_votes_on_same_poll(vote).exists?
  37. end
  38. end
  39. def account_votes_on_same_poll(vote)
  40. vote.poll.votes.where(account: vote.account)
  41. end
  42. end