Сделать имя таблицы уникальным только для пользователя, а не для всей базы данных - PullRequest
0 голосов
/ 27 марта 2020

У меня здесь, например, пользователь со многими группами и база данных структурирована следующим образом:

class CreateGroups < ActiveRecord::Migration[6.0]
  def change
    create_table :groups, id: :uuid do |t|
      t.uuid    :user_id
      t.string  :name

      t.timestamps
    end

    add_index :groups, :name, unique: true
  end
end

Приведенное выше делает name уникальным для всей базы данных. Я хочу, чтобы name был уникальным для пользователя (user_id). Это возможно на уровне базы данных? Чтобы получить что-то подобное, нужно ли мне вместо этого использовать find или create ?

Если у меня два пользователя, они должны иметь возможность создавать одинаковые имена групп, но не должны быть одинаковыми для каждого пользователя:

User.first.groups.first.name #> Bold
User.first.groups.second.name #> Bold (should fail)

User.second.groups.first.name #> Bold (should be ok)
User.second.groups.second.name #> Bold (should fail)

Ответы [ 2 ]

3 голосов
/ 27 марта 2020

Он называется многоколоночным индексом (он же составной индекс, комбинированный индекс или составной индекс), и вы можете создать их, передав массив:

class CreateGroups < ActiveRecord::Migration[6.0]
  def change
    create_table :groups, id: :uuid do |t|
      t.uuid    :user_id
      t.string  :name
      t.timestamps
    end

    add_index :groups, [:user_id, :name], unique: true
  end
end

На стороне приложения вы можете проверить это с помощью:

class Group < ApplicationRecord
  validates :name, uniqueness: { scope: :user_id }
end

Это обеспечивает обратную связь с пользователем и предотвращает ошибку драйвера базы данных, в то время как фактический индекс БД защищает от состояния гонки .

2 голосов
/ 27 марта 2020

Просто измените

add_index :groups, :name, unique: true

на

add_index :groups, [:user_id, :name], unique: true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...