Files
nairobi/app/models/poll/voter.rb
Javi Martín 096f546c24 Make sure users only vote once in the same poll
When skipping verification, we cannot apply the validation rule saying
the document number and document type must be unique, because they'll be
`nil` in many cases. So we were skipping the rule, but that makes it
possible for the same user to vote several times (for instance, once in
a booth and once via web).

So we're changing the scope of the uniqueness rule: instead of being
unique per document number, voters are unique per user. The reason we
made them unique per document number was that back in commit 900563e3
(when we added the rule), we hadn't added the relation between users and
poll voters yet.
2020-08-07 13:40:25 +02:00

53 lines
1.5 KiB
Ruby

class Poll
class Voter < ApplicationRecord
VALID_ORIGINS = %w[web booth letter].freeze
belongs_to :poll
belongs_to :user
belongs_to :geozone
belongs_to :booth_assignment
belongs_to :officer_assignment
belongs_to :officer
validates :poll_id, presence: true
validates :user_id, presence: true
validates :booth_assignment_id, presence: true, if: ->(voter) { voter.origin == "booth" }
validates :officer_assignment_id, presence: true, if: ->(voter) { voter.origin == "booth" }
validates :document_number, presence: true, unless: :skip_user_verification?
validates :user_id, uniqueness: { scope: [:poll_id], message: :has_voted }
validates :origin, inclusion: { in: VALID_ORIGINS }
before_validation :set_demographic_info, :set_document_info, :set_denormalized_booth_assignment_id
scope :web, -> { where(origin: "web") }
scope :booth, -> { where(origin: "booth") }
scope :letter, -> { where(origin: "letter") }
def set_demographic_info
return if user.blank?
self.gender = user.gender
self.age = user.age
self.geozone = user.geozone
end
def set_document_info
return if user.blank?
self.document_type = user.document_type
self.document_number = user.document_number
end
def skip_user_verification?
Setting["feature.user.skip_verification"].present?
end
private
def set_denormalized_booth_assignment_id
self.booth_assignment_id ||= officer_assignment&.booth_assignment_id
end
end
end