Nous avons la syntaxe script/generate migration add_fieldname_to_tablename fieldname:datatype
pour ajouter de nouvelles colonnes à un modèle.
Sur la même ligne, avons-nous un script/generate pour changer le type de données d'une colonne? Ou devrais-je écrire SQL directement dans ma migration Vanilla?
Je veux changer une colonne de datetime
à date
.
Je pense que cela devrait fonctionner.
change_column :table_name, :column_name, :date
Vous pouvez également utiliser un bloc si vous avez plusieurs colonnes à modifier dans une table.
Exemple:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
Voir la documentation API sur la classe Table pour plus de détails.
Je ne sais pas si vous pouvez créer une migration à partir de la ligne de commande pour faire tout cela, mais vous pouvez créer une nouvelle migration, puis éditer la migration pour effectuer cela.
Si nom_table est le nom de votre table, nom_zone est le nom de votre champ et que vous souhaitez passer d'une date à une date, vous pouvez écrire une migration à cette fin.
Vous pouvez créer une nouvelle migration avec:
Rails g migration change_data_type_for_fieldname
Puis éditez la migration pour utiliser change_table:
class ChangeDataTypeForFieldname < ActiveRecord::Migration
def self.up
change_table :tablename do |t|
t.change :fieldname, :date
end
end
def self.down
change_table :tablename do |t|
t.change :fieldname, :datetime
end
end
end
Puis lancez la migration:
rake db:migrate
Comme je l'ai trouvé dans les réponses précédentes, trois étapes sont nécessaires pour changer le type d'une colonne:
Étape 1:
Générez un nouveau fichier de migration en utilisant ce code:
Rails g migration sample_name_change_column_type
Étape 2:
Accédez au dossier /db/migrate
et modifiez le fichier de migration que vous avez créé. Il y a deux solutions différentes.
def change
change_column(:table_name, :column_name, :new_type)
end
2.
def up
change_column :table_name, :column_name, :new_type
end
def down
change_column :table_name, :column_name, :old_type
end
Étape 3:
N'oubliez pas de faire cette commande:
rake db:migrate
J'ai testé cette solution pour Rails 4 et cela fonctionne bien.
De Rails Guides :
Si vous souhaitez qu'une migration fasse quelque chose qu'Active Record ne sait pas inverser, vous pouvez utiliser
reversible
:
class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
def change
reversible do |dir|
change_table :tablename do |t|
dir.up { t.change :fieldname, :date }
dir.down { t.change :fieldname, :datetime }
end
end
end
end
Il suffit de générer une migration:
Rails g migration change_column_to_new_from_table_name
Mettez à jour la migration comme ceci:
class ClassName < ActiveRecord::Migration
change_table :table_name do |t|
t.change :column_name, :data_type
end
end
et enfin
rake db:migrate
Une autre façon de changer le type de données en utilisant la migration
étape 1: Vous devez supprimer le nom de champ du type de données défaillant à l'aide de la migration.
ex:
Rails g migration RemoveFieldNameFromTableName field_name:data_type
Ici, n'oubliez pas de spécifier le type de données pour votre champ
Étape 2: Maintenant, vous pouvez ajouter un champ avec le type de données correct
ex:
Rails g migration AddFieldNameToTableName field_name:data_type
Ça y est, maintenant votre table sera ajoutée avec le champ de type de données correct, codage Happy Ruby !!
Compléter les réponses en cas d’édition valeur par défaut :
Dans votre console Rails:
Rails g migration MigrationName
Dans la migration:
def change
change_column :tables, :field_name, :field_type, default: value
end
Ressemblera :
def change
change_column :members, :approved, :boolean, default: true
end
Tout cela suppose que le type de données de la colonne ait une conversion implicite pour toutes les données existantes. J'ai rencontré plusieurs situations dans lesquelles les données existantes, disons une String
peuvent être implicitement converties dans le nouveau type de données, disons Date
.
Dans ce cas, il est utile de savoir que vous pouvez créer des migrations avec des conversions de données. Personnellement, j'aime bien les placer dans mon fichier de modèle, puis les supprimer une fois que tous les schémas de base de données ont été migrés et sont stables.
/app/models/table.rb
...
def string_to_date
update(new_date_field: date_field.to_date)
end
def date_to_string
update(old_date_field: date_field.to_s)
end
...
def up
# Add column to store converted data
add_column :table_name, :new_date_field, :date
# Update the all resources
Table.all.each(&:string_to_date)
# Remove old column
remove_column :table_name, :date_field
# Rename new column
rename_column :table_name, :new_date_field, :date_field
end
# Reversed steps does allow for migration rollback
def down
add_column :table_name, :old_date_field, :string
Table.all.each(&:date_to_string)
remove_column :table_name, :date_field
rename_column :table_name, :old_date_field, :date_field
end