Есть ли способ рельсового способа проверки того, что фактическая запись уникальна, а не только столбец? Например, модель / таблица дружбы не должна иметь несколько одинаковых записей, таких как:
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
Is there a rails-way way
. И вы предлагаете ему не рельсовый путь, а стандартный.The Active Record way claims that intelligence belongs in your models, not in the database.
validates :field_name, unique: true
, склонен к гоночным условиям, поэтому, несмотря на рельсовые пути, предпочтение отдается фактическим ограничениям. @HarryJoy Я опишу ответ, описывающий способ ограничения.Ответы:
Вы можете выполнить
validates_uniqueness_of
вызов следующим образом.источник
validates_uniqueness_of [:user_id, :friend_id]
. Может быть, это должно быть исправлено?Ты можешь использовать
validates
для проверкиuniqueness
по одному столбцу:Синтаксис проверки для нескольких столбцов аналогичен, но вместо этого вы должны предоставить массив полей:
Однако приведенные выше подходы к проверке имеют условие состязания и не могут обеспечить согласованность. Рассмотрим следующий пример:
Записи таблицы базы данных должны быть уникальными n полям;
несколько ( два или более ) одновременных запросов, обрабатываемых отдельными процессами каждый ( серверы приложений, фоновые рабочие серверы или что вы используете ), обращайтесь к базе данных, чтобы вставить одну и ту же запись в таблицу;
каждый процесс параллельно проверяет, есть ли запись с тем же n полями;
проверка для каждого запроса проходит успешно, и каждый процесс создает запись в таблице с теми же данными.
Чтобы избежать такого поведения, нужно добавить уникальное ограничение в таблицу БД. Вы можете установить его с помощью
add_index
помощника для одного (или нескольких) полей, выполнив следующую миграцию:Предупреждение : даже после того, как вы установили уникальное ограничение, два или более одновременных запроса будут пытаться записать одни и те же данные в базу данных, но вместо создания дублированных записей это вызовет
ActiveRecord::RecordNotUnique
исключение, которое вы должны обработать отдельно:источник
Это может быть сделано с ограничением базы данных на двух столбцах:
add_index :friendships, [:user_id, :friend_id], unique: true
Вы можете использовать валидатор rails, но в целом я рекомендую использовать ограничение базы данных.
Больше чтения: https://robots.thoughtbot.com/validation-database-constraint-or-both
источник