Индекс уникальных рельсов Mutli-столбцов работает некорректно
Я изо всех сил пытаюсь понять это:
у меня есть User
модель с адресом электронной почты и дополнительным адресом электронной почты, которые они могут использовать для входа в систему. Пользователь не должен иметь такой же адрес электронной почты / дополнительный адрес электронной почты, как другой пользователь. Два столбца также должны быть взаимно уникальными.
Что происходит
Однако мои индексы проверяют уникальность только в своем собственном столбце. Таким образом, пользователь не может иметь тот же адрес электронной почты, что и другой пользователь, и он не может иметь тот же дополнительный адрес электронной почты, что и другой дополнительный адрес электронной почты.
Индекс, который обеспечивает уникальность этих двух столбцов и добавляет уникальный индекс для электронной почты и вторичной электронной почты.
Но индексы не работают через два столбца
Что ожидается
Пользователь не должен иметь возможность использовать электронную почту, которая существует в базе данных, в качестве электронной почты или дополнительной электронной почты.
migration.rb
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :email, null: false
t.string :secondary_email
t.timestamps
end
add_index :users, [:email, :secondary_email], unique: true
add_index :users, [:secondary_email, :email], unique: true
add_index :users, :secondary_email, unique: true
add_index :users, :email, unique: true
end
end
Я перепробовал все комбинации с индексами. Без нижних единичных индексов у пользователя может быть такой же email
пока их secondary_email
с были уникальными.
1 ответ
Пользователь не должен иметь возможность использовать электронную почту, которая существует в базе данных, в качестве электронной почты или дополнительной электронной почты.
Единственный способ избежать подобных случаев - сделать пользовательские проверки. Что-то вроде ниже должно работать
class User < ActiveRecord::Base
validate :verify_unique_email_or_secondary_email
def verify_unique_email_or_secondary_email
if User.exists?("email = ? OR secondary_email = ?", email,email)
errors.add(:email, 'Email or Secondary Email has already been taken')
end
end
end