web-dev-qa-db-fra.com

Ajouter une migration de colonne de référence dans Rails 4

Un utilisateur a de nombreux téléchargements. Je souhaite ajouter une colonne à la table uploads qui fait référence à user. À quoi devrait ressembler la migration?

Voici ce que j'ai. Je ne suis pas sûr de devoir utiliser (1) :user_id, :int ou (2) :user, :references. Je ne suis même pas sûr si (2) fonctionne. J'essaie juste de faire cela de la manière "Rails".

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_column :uploads, :user_id, :integer
  end
end

Question pertinente sauf pour Rails 3. Migrations Rails 3: ajout de la colonne de référence?

289
Don P

Rails 4.x

Lorsque vous avez déjà users et uploads tables et souhaitez ajouter une nouvelle relation entre eux.

Il vous suffit de générer une migration à l'aide de la commande suivante:

Rails g migration AddUserToUploads user:references

Ce qui va créer un fichier de migration en tant que:

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_reference :uploads, :user, index: true
  end
end

Ensuite, lancez la migration en utilisant rake db:migrate. Cette migration prendra en charge l’ajout d’une nouvelle colonne nommée user_id à la table uploads (faisant référence à la colonne id de la table users), PLUS ajoutera également un index à la nouvelle colonne.

UPDATE [For Rails 4.2]

On ne peut pas faire confiance aux rails pour maintenir l’intégrité référentielle; des bases de données relationnelles viennent ici à notre secours. Cela signifie que nous pouvons ajouter des contraintes de clé étrangère au niveau de la base de données et veiller à ce que la base de données rejette toute opération qui enfreint l'intégrité référentielle définie. Comme @infoget a commenté, Rails 4.2 est livré avec un support natif pour clés étrangères (intégrité référentielle) . Ce n'est pas obligatoire, mais vous voudrez peut-être ajouter une clé étrangère (très utile) à la référence que nous avons créée ci-dessus.

Pour ajouter une clé étrangère à une référence existante , créez une nouvelle migration pour ajouter une clé étrangère:

class AddForeignKeyToUploads < ActiveRecord::Migration
  def change
    add_foreign_key :uploads, :users
  end
end

Pour créer une toute nouvelle référence complètement avec une clé étrangère (dans Rails 4.2) , générez une migration à l'aide de la commande suivante:

Rails g migration AddUserToUploads user:references

qui créera un fichier de migration en tant que:

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_reference :uploads, :user, index: true
    add_foreign_key :uploads, :users
  end
end

Cela ajoutera une nouvelle clé étrangère à la colonne user_id de la table uploads. La clé fait référence à la colonne id de la table users.

REMARQUE: En plus de l'ajout d'une référence, vous devez toujours créer une référence d'abord, puis une clé étrangère (, vous pouvez choisir de créer une clé étrangère dans la même migration ou dans un fichier de migration séparé ). Active Record ne prend en charge que les clés étrangères à une colonne et actuellement, seuls les adaptateurs mysql, mysql2 et PostgreSQL sont pris en charge. N'essayez pas ceci avec d'autres adaptateurs comme sqlite3, etc. Reportez-vous à Guides de rails: clés étrangères pour votre référence.

661
Kirti Thorat

Rails 5

Vous pouvez toujours utiliser cette commande pour créer la migration:

Rails g migration AddUserToUploads user:references

La migration semble un peu différente de la précédente, mais fonctionne toujours:

class AddUserToUploads < ActiveRecord::Migration[5.0]
  def change
    add_reference :uploads, :user, foreign_key: true
  end
end

Notez que c'est :user, pas :user_id

165
Mirror318

si vous aimez une autre approche alternative avec la méthode up et down, essayez ceci:

  def up
    change_table :uploads do |t|
      t.references :user, index: true
    end
  end

  def down
    change_table :uploads do |t|
      t.remove_references :user, index: true
    end
  end
15
Kiry Meas

[Utilisation de Rails 5]

Générer la migration:

Rails generate migration add_user_reference_to_uploads user:references

Cela créera le fichier de migration:

class AddUserReferenceToUploads < ActiveRecord::Migration[5.1]
  def change
    add_reference :uploads, :user, foreign_key: true
  end
end

Maintenant, si vous observez le fichier de schéma, vous verrez que la table uploads contient un nouveau champ. Quelque chose comme: t.bigint "user_id" ou t.integer "user_id".

Migrer la base de données:

Rails db:migrate
9
vantony

Une autre syntaxe pour faire la même chose est la suivante:

Rails g migration AddUserToUpload user:belongs_to
7
Nadeem Yasin

Juste pour documenter si quelqu'un a le même problème ...

Dans ma situation, j'ai utilisé les champs :uuid, et les réponses ci-dessus ne fonctionnent pas dans mon cas, car Rails 5 créent une colonne utilisant :bigint à la place :uuid:

add_column :uploads, :user_id, :uuid
add_index :uploads, :user_id
add_foreign_key :uploads, :users
4
Bruno Casali