#ruby-on-rails-3 #validation #unique
#ruby-on-rails-3 #проверка #уникальный
Вопрос:
У меня есть следующая настройка:
class Vote < ActiveRecord::Base
belongs_to :voteable, :polymorphic => :true, :counter_cache => true
end
class Proposition < ActiveRecord::Base
has_many :votes, :as => :voteable
end
class Winner < ActiveRecord::Base
has_many :votes, :as => :voteable
end
Таблица голосования выглядит следующим образом:
t.string "ip_address"
t.integer "voteable_id"
t.string "voteable_type"
Я хочу проверить следующее. Пользователь с заданным ip_address может проголосовать только за 1 предложение. Таким образом, комбинация ip_address, voteable_id и voteable_type должна быть уникальной.
Как я могу добиться этого с помощью «простого» правила проверки?
Ответ №1:
Чтобы гарантировать уникальность, вы должны добавить уникальный индекс в свою базу данных
Если у вас еще нет важных данных, вы можете сделать это внутри миграции с помощью add_index
add_index(:votes, [:ip_address, :voteable_id, voteable_type], :unique => true, :name => 'allowed_one_vote')
если у вас уже есть какие-то данные, это можно сделать с помощью SQL, и это зависит от вашей СУБД
Комментарии:
1. это зависит от вас, если производительность в порядке, вы можете оставить все как есть
2. Это не отвечает на вопрос. Спрашивающий хотел получить проверку. Если для этой ситуации действительно нет конкретной проверки, ответ заключается в том, чтобы просто выполнить пользовательскую проверку. Это может быть или не быть «лучшим» способом (что зависит от ситуации), но выполнение ограничения DB по сравнению с проверкой — это яблоки и апельсины.
Ответ №2:
Добавьте область действия к :ip_address
проверке уникальности
class Vote < ActiveRecord::Base
# ...
validates :ip_address, uniqueness: { scope: [:voteable_type, :voteable_id]}
end