Вам нужна уникальная область действия
validates :ip_address, uniqueness: { scope: :answer_id }
Это не позволит дублировать ip_address
за answer
https://guides.rubyonrails.org/active_record_validations.html#uniqueness
Вы также можете применить его на уровне базы данных, добавив его в миграцию, хотя это и необязательно, но
add_index :votes, [:ip_address, :answer_id], unique: true
Но приведенное выше решение не позволит пользователю не голосовать за ответ более одного раза. Если вам нужна уникальность с poll
, один из вариантов - сохранить poll_id
в таблице answers
, а затем определить уникальность для этого,
, или, во-вторых, определить пользовательскую проверку в Vote
модель
validate :uniqueness_with_poll
def uniqueness_with_poll
errors.add(:answer_id, 'already voted for poll') if answer_for_poll_exists?
end
def answer_for_poll_exists?
answer_voted = Vote.where(ip_address: ip_address).pluck(:answer_id)
return false if answer_voted.blank?
answer.poll.answers.where(id: answer_voted).exists?
end
Затем определим метод answer_for_poll_exists?
, чтобы проверить, проголосовал ли уже опрос, но это может быть дорогостоящим.
Надеюсь, это поможет!