Индекс уникальных рельсов 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
Другие вопросы по тегам