web-dev-qa-db-fra.com

Comment rendre une colonne unique et l'indexer dans une migration Ruby on Rails?

J'aimerais créer une colonne unique dans le script de migration Ruby on Rails. Quelle est la meilleure façon de le faire? Est-il également possible d'indexer une colonne dans une table?

Je voudrais appliquer des colonnes unique dans une base de données au lieu d'utiliser simplement :validate_uniqueness_of.

352
Tam

La réponse courte:

add_index :table_name, :column_name, unique: true

Pour indexer plusieurs colonnes ensemble, vous passez un tableau de noms de colonnes au lieu d’un nom de colonne unique.

add_index :table_name, [:column_name_a, :column_name_b], unique: true

Pour un contrôle plus fin, il existe une méthode "execute" qui exécute du code SQL direct.

C'est tout!

Si vous faites cela pour remplacer les anciennes validations de modèles, vérifiez simplement comment cela fonctionne. Je ne suis pas sûr que le signalement des erreurs à l'utilisateur sera aussi agréable. Vous pouvez toujours faire les deux. 

615
ndp

Rails génèrent la migration add_index_to_table_name nom_colonne: uniq

ou

Les Rails génèrent la migration add_nom_colonne_nom_table_nom_colonne: chaîne: uniq: index

génère

class AddIndexToModerators < ActiveRecord::Migration
  def change
    add_column :moderators, :username, :string
    add_index :moderators, :username, unique: true
  end
end

Si vous ajoutez un index à une colonne existante, supprimez ou commentez la ligne add_column, ou cochez

add_column :moderators, :username, :string unless column_exists? :moderators, :username
111
d.danailov

Comme cela n'a pas encore été mentionné mais répond à la question que j'avais lorsque j'ai trouvé cette page, vous pouvez également spécifier qu'un index doit être unique lors de l'ajout via t.references ou t.belongs_to:

create_table :accounts do |t|
  t.references :user, index: { unique: true } # or t.belongs_to

  # other columns...
end

(à partir d'au moins Rails 4.2.7)

34
Steve Grossi

Si vous créez une nouvelle table, vous pouvez utiliser le raccourci en ligne:

  def change
    create_table :posts do |t|
      t.string :title, null: false, index: { unique: true }
      t.timestamps
    end
  end
20
Pioz

J'utilise Rails 5 et les réponses ci-dessus fonctionnent très bien. voici une autre façon qui a également fonctionné pour moi (le nom de la table est :people et le nom de la colonne est :email_address)

class AddIndexToEmailAddress < ActiveRecord::Migration[5.0]
  def change
    change_table :people do |t|
      t.index :email_address, unique: true
    end
  end
end
12
Nicholas Nelson
add_index :table_name, :column_name, unique: true

Pour indexer plusieurs colonnes ensemble, vous transmettez un tableau de noms de colonnes au lieu d'un seul nom de colonne.

1
murali

Vous voudrez peut-être ajouter un nom à la clé unique car le nombre de fois que le nom unique_key par défaut de Rails peut être trop long pour lequel la base de données peut générer l'erreur.

Pour ajouter un nom à votre index, utilisez simplement l'option name: . La requête de migration pourrait ressembler à ceci:

add_index :table_name, [:column_name_a, :column_name_b, ... :column_name_n], unique: true, name: 'my_custom_index_name'

Plus d'infos - http://apidock.com/Rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

0
Swaps

Si vous avez oublié d'ajouter unique à la colonne de base de données, ajoutez simplement cette validation dans le modèle pour vérifier si le champ est unique:

class Person < ActiveRecord::Base
  validates_uniqueness_of :user_name
end

référez-vous ici Comme indiqué ci-dessus, veuillez ajouter index en modifiant la colonne de la base de données, comme suggéré par @Nate.

veuillez vous référer à ceci avec index pour plus d'informations

0
Ravistm