Проверка уникальности Rails с помощью вложенного has_many - PullRequest
1 голос
/ 24 января 2020

Я создаю веб-сайт Опросы и хочу, чтобы пользователь (ip-адрес) мог голосовать один раз за опрос. У меня есть следующие модели:

class Poll < ApplicationRecord
  has_many :answers, :dependent => :destroy
  accepts_nested_attributes_for :answers, allow_destroy: true
end

class Answer < ApplicationRecord
  belongs_to :poll
  has_many :votes
end

class Vote < ApplicationRecord
  validates_uniqueness_of :ip_address
  belongs_to :answer
end

С моим текущим решением пользователь может проголосовать один раз в одном опросе, а затем он не может голосовать в другом. Что я должен использовать для validates_uniqueness_of :ip_address за опрос? Я пытался использовать область опроса, но это не сработало.

PS: Я знаю, что IP-адрес - не лучшее решение для проверки уникальных голосов.

1 Ответ

3 голосов
/ 24 января 2020

Вам нужна уникальная область действия

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?, чтобы проверить, проголосовал ли уже опрос, но это может быть дорогостоящим.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...