Ruby on Rails
Migrations ActiveRecord
Recherche…
Paramètres
Type de colonne | La description |
---|---|
:primary_key | Clé primaire |
:string | Type de données de chaîne plus court. Permet l'option limit pour le nombre maximum de caractères. |
:text | Plus grande quantité de texte Permet l'option limit pour le nombre maximum d'octets. |
:integer | Entier. Permet l'option limit pour le nombre maximum d'octets. |
:bigint | Entier plus grand |
:float | Flotte |
:decimal | Nombre décimal avec précision variable. Permet precision options de precision et d' scale . |
:numeric | Permet precision options de precision et d' scale . |
:datetime | Objet DateTime pour les dates / heures. |
:time | Objet de temps pour les temps. |
:date | Objet date pour les dates. |
:binary | Données binaires. Permet l'option limit pour le nombre maximum d'octets. |
:boolean | Booléen |
Remarques
La plupart des fichiers de migration sont
db/migrate/
dansdb/migrate/
répertoiredb/migrate/
. Ils sont identifiés par un horodatage UTC au début de leur nom de fichier:YYYYMMDDHHMMSS_create_products.rb
.La commande de
rails generate
peut être raccourcie enrails g
.Si un
:type
n'est pas transmis à un champ, sa valeur par défaut est une chaîne.
Exécuter une migration spécifique
Pour exécuter une migration spécifique vers le haut ou le bas, utilisez db:migrate:up
ou db:migrate:down
.
Mettre en place une migration spécifique:
rake db:migrate:up VERSION=20090408054555
rails db:migrate:up VERSION=20090408054555
En bas d'une migration spécifique:
rake db:migrate:down VERSION=20090408054555
rails db:migrate:down VERSION=20090408054555
Le numéro de version dans les commandes ci-dessus est le préfixe numérique dans le nom de fichier de la migration. Par exemple, pour migrer vers la migration 20160515085959_add_name_to_users.rb
, vous utiliseriez 20160515085959
comme numéro de version.
Créer une table de jointure
Pour créer une table de jointure entre les students
et les courses
, exécutez la commande suivante:
$ rails g migration CreateJoinTableStudentCourse student course
Cela générera la migration suivante:
class CreateJoinTableStudentCourse < ActiveRecord::Migration[5.0]
def change
create_join_table :students, :courses do |t|
# t.index [:student_id, :course_id]
# t.index [:course_id, :student_id]
end
end
end
Exécution de migrations dans différents environnements
Pour exécuter des migrations dans l'environnement de test
, exécutez cette commande shell:
rake db:migrate RAILS_ENV=test
À partir de Rails 5.0, vous pouvez utiliser des rails
au lieu de rake
:
rails db:migrate RAILS_ENV=test
Ajouter une nouvelle colonne à une table
Pour ajouter un nouveau name
colonne à la table users
, exécutez la commande:
rails generate migration AddNameToUsers name
Cela génère la migration suivante:
class AddNameToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
end
end
Lorsque le nom de la migration est de la forme AddXXXToTABLE_NAME
suivi d'une liste de colonnes avec des types de données, la migration générée contiendra les instructions add_column
appropriées.
Ajouter une nouvelle colonne avec un index
Pour ajouter un nouvel email
colonne indexée à la table users
, exécutez la commande:
rails generate migration AddEmailToUsers email:string:index
Cela générera la migration suivante:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email
end
end
Supprimer une colonne existante d'une table
Pour supprimer un name
de colonne existant de la table users
, exécutez la commande:
rails generate migration RemoveNameFromUsers name:string
Cela générera la migration suivante:
class RemoveNameFromUsers < ActiveRecord::Migration[5.0]
def change
remove_column :users, :name, :string
end
end
Lorsque le nom de la migration est de la forme RemoveXXXFromYYY
suivi d'une liste de colonnes avec des types de données, la migration générée contiendra les instructions remove_column
appropriées.
Bien qu'il ne soit pas nécessaire de spécifier le type de données (par exemple :string
) en tant que paramètre de remove_column
, il est fortement recommandé. Si le type de données n'est pas spécifié, la migration ne sera pas réversible.
Ajouter une colonne de référence à une table
Pour ajouter une référence à une team
à la table d' users
, exécutez cette commande:
$ rails generate migration AddTeamRefToUsers team:references
Cela génère la migration suivante:
class AddTeamRefToUsers < ActiveRecord::Migration[5.0]
def change
add_reference :users, :team, foreign_key: true
end
end
Cette migration créera une colonne team_id
dans la table users
.
Si vous souhaitez ajouter un index
approprié et foreign_key
sur la colonne ajoutée, modifiez la commande pour que les rails generate migration AddTeamRefToUsers team:references:index
. Cela générera la migration suivante:
class AddTeamRefToUsers < ActiveRecord::Migration
def change
add_reference :users, :team, index: true
add_foreign_key :users, :teams
end
end
Si vous souhaitez nommer votre colonne de référence autre que celle générée automatiquement par Rails, ajoutez ce qui suit à votre migration: (Par exemple, vous pouvez appeler l' User
qui a créé la Post
tant Author
dans la table des Post
)
class AddAuthorRefToPosts < ActiveRecord::Migration
def change
add_reference :posts, :author, references: :users, index: true
end
end
Créer une nouvelle table
Pour créer une nouvelle table d' users
avec le name
et le salary
colonnes, exécutez la commande:
rails generate migration CreateUsers name:string salary:decimal
Cela générera la migration suivante:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.decimal :salary
end
end
end
Lorsque le nom de la migration est de la forme CreateXXX
suivi d'une liste de colonnes avec des types de données, une migration sera générée pour créer la table XXX
avec les colonnes répertoriées.
Ajout de plusieurs colonnes à une table
Pour ajouter plusieurs colonnes à une table, séparez les field:type
paires avec des espaces lorsque vous utilisez des rails generate migration
commande de rails generate migration
.
La syntaxe générale est la suivante:
rails generate migration NAME [field[:type][:index] field[:type][:index]] [options]
Par exemple, les éléments suivants ajouteront les champs name
, salary
et email
au tableau des users
:
rails generate migration AddDetailsToUsers name:string salary:decimal email:string
Qui génère la migration suivante:
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :name, :string
add_column :users, :salary, :decimal
add_column :users, :email, :string
end
end
Exécution de migrations
Exécuter la commande:
rake db:migrate
rails db:migrate
La spécification de la version cible exécutera les migrations requises (haut, bas, modification) jusqu'à ce qu'elle atteigne la version spécifiée. Ici, le version number
est le préfixe numérique du nom de fichier de la migration.
rake db:migrate VERSION=20080906120000
rails db:migrate VERSION=20080906120000
Migrations de restauration
Pour rollback
la dernière migration, soit en annulant la méthode de change
, soit en exécutant la méthode down
. Exécuter la commande:
rake db:rollback
rails db:rollback
Rétrograder les 3 dernières migrations
rake db:rollback STEP=3
rails db:rollback STEP=3
STEP
fournit le nombre de migrations à restaurer.
Annuler toutes les migrations
rake db:rollback VERSION=0
rails db:rollback VERSION=0
Tables à langer
Si vous avez créé une table avec un schéma incorrect, le moyen le plus simple de modifier les colonnes et leurs propriétés est change_table
. Consultez l'exemple suivant:
change_table :orders do |t|
t.remove :ordered_at # removes column ordered_at
t.string :skew_number # adds a new column
t.index :skew_number #creates an index
t.rename :location, :state #renames location column to state
end
La migration ci-dessus modifie les orders
une table. Voici une description ligne par ligne des modifications:
-
t.remove :ordered_at
supprime laordered_at
desorders
de la table. -
t.string :skew_number
ajoute une nouvelle colonne de type chaîne nomméeskew_number
dans la tableorders
. -
t.index :skew_number
ajoute un index sur la colonneskew_number
de la tableorders
. -
t.rename :location, :state
renomme la colonne d'location
dans la table desorders
pourstate
.
Ajouter une colonne unique à une table
Pour ajouter un nouvel email
colonne unique aux users
, exécutez la commande suivante:
rails generate migration AddEmailToUsers email:string:uniq
Cela créera la migration suivante:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
add_index :users, :email, unique: true
end
end
Changer le type d'une colonne existante
Pour modifier une colonne existante dans Rails avec une migration, exécutez la commande suivante:
rails g migration change_column_in_table
Cela créera un nouveau fichier de migration dans le répertoire db/migration
(s'il n'existe pas déjà), qui contiendra le fichier avec le préfixe timestamp et le nom du fichier de migration qui contient le contenu ci-dessous:
def change
change_column(:table_name, :column_name, :new_type)
end
Guide Rails - Modification des colonnes
Une méthode plus longue mais plus sûre
Le code ci-dessus empêche l'utilisateur de revenir en arrière sur la migration. Vous pouvez éviter ce problème en divisant le change
méthode dans différents up
le down
up
et down
le down
des méthodes:
def up
change_column :my_table, :my_column, :new_type
end
def down
change_column :my_table, :my_column, :old_type
end
Refaire les migrations
Vous pouvez restaurer, puis migrer à nouveau à l'aide de la commande redo
. Il s’agit essentiellement d’un raccourci combinant des tâches de rollback
et de migrate
.
Exécuter la commande:
rake db:migrate:redo
rails db:migrate:redo
Vous pouvez utiliser le paramètre STEP
pour revenir sur plusieurs versions.
Par exemple, pour revenir en arrière de 3 migrations:
rake db:migrate:redo STEP=3
rails db:migrate:redo STEP=3
Ajouter une colonne avec une valeur par défaut
L'exemple suivant ajoute une colonne admin
à la table users
et attribue à cette colonne la valeur par défaut false
.
class AddDetailsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
Les migrations avec des valeurs par défaut peuvent prendre beaucoup de temps dans les grandes tables avec, par exemple, PostgreSQL. En effet, chaque ligne devra être mise à jour avec la valeur par défaut de la colonne nouvellement ajoutée. Pour contourner ce problème (et réduire les temps d'arrêt pendant les déploiements), vous pouvez diviser votre migration en trois étapes:
- Ajouter un
add_column
-migration similaire à celui ci-dessus, mais ne pas définir par défaut - Déployez et mettez à jour la colonne dans une tâche rake ou sur la console pendant que votre application est en cours d'exécution. Assurez-vous que votre application écrit déjà des données dans cette colonne pour les lignes nouvelles / mises à jour.
- Ajouter une autre migration
change_column
, qui modifie ensuite la valeur par défaut de cette colonne à la valeur par défaut souhaitée
Interdire les valeurs nulles
Pour interdire null
valeurs null
dans vos colonnes de table, ajoutez le paramètre :null
à votre migration, comme ceci:
class AddPriceToProducts < ActiveRecord::Migration
def change
add_column :products, :float, null: false
end
end
Vérification du statut de migration
Nous pouvons vérifier l'état des migrations en exécutant
rake db:migrate:status
rails db:migrate:status
La sortie ressemblera à ceci:
Status Migration ID Migration Name
--------------------------------------------------
up 20140711185212 Create documentation pages
up 20140724111844 Create nifty attachments table
up 20140724114255 Create documentation screenshots
up 20160213170731 Create owners
up 20160218214551 Create users
up 20160221162159 ********** NO FILE **********
up 20160222231219 ********** NO FILE **********
Dans le champ d'état, up
signifie la migration a été exécuté et down
le down
signifie que nous devons exécuter la migration.
Créer une colonne hstore
Hstore
colonnes Hstore
peuvent être utiles pour stocker des paramètres. Ils sont disponibles dans les bases de données PostgreSQL après avoir activé l'extension.
class CreatePages < ActiveRecord::Migration[5.0]
def change
create_table :pages do |t|
enable_extension 'hstore' unless extension_enabled?('hstore')
t.hstore :settings
t.timestamps
end
end
end
Ajouter une référence personnelle
Une référence automatique peut être utile pour construire un arbre hiérarchique. Cela peut être réalisé avec add_reference
dans une migration.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_reference :pages, :pages
end
end
La colonne de clé étrangère sera pages_id
. Si vous souhaitez décider du nom de la colonne de clé étrangère, vous devez d'abord créer la colonne et ajouter la référence après.
class AddParentPages < ActiveRecord::Migration[5.0]
def change
add_column :pages, :parent_id, :integer, null: true, index: true
add_foreign_key :pages, :pages, column: :parent_id
end
end
Créer une colonne de tableau
Une colonne de array
est prise en charge par PostgreSQL. Rails convertira automatiquement un tableau PostgreSQL en un tableau Ruby, et inversement.
Créez une table avec une colonne de array
:
create_table :products do |t|
t.string :name
t.text :colors, array: true, default: []
end
Ajoutez une colonne de array
à une table existante:
add_column :products, :colors, array: true, default: []
Ajoutez un index pour une colonne de array
:
add_index :products, :colors, using: 'gin'
Ajout d'une contrainte NOT NULL aux données existantes
Supposons que vous souhaitiez ajouter une clé étrangère company_id
à la table users
et que vous souhaitiez avoir une contrainte NOT NULL
. Si vous avez déjà des données dans les users
, vous devrez le faire en plusieurs étapes.
class AddCompanyIdToUsers < ActiveRecord::Migration
def up
# add the column with NULL allowed
add_column :users, :company_id, :integer
# make sure every row has a value
User.find_each do |user|
# find the appropriate company record for the user
# according to your business logic
company = Company.first
user.update!(company_id: company.id)
end
# add NOT NULL constraint
change_column_null :users, :company_id, false
end
# Migrations that manipulate data must use up/down instead of change
def down
remove_column :users, :company_id
end
end