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?
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.
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
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
[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
Une autre syntaxe pour faire la même chose est la suivante:
Rails g migration AddUserToUpload user:belongs_to
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