J'ai créé une colonne de date dans une migration précédente et je l'ai définie sur nullable. Maintenant, je veux changer pour ne pas être annulable. Comment puis-je faire cela en supposant qu'il y a des lignes nulles dans cette base de données? Je suis d'accord pour définir ces colonnes sur Time.now si elles sont actuellement nulles.
Si vous le faites dans une migration, vous pouvez probablement le faire comme ceci:
# Make sure no null value exist
MyModel.where(date_column: nil).update_all(date_column: Time.now)
# Change the column to not allow null
change_column :my_models, :date_column, :datetime, null: false
Dans Rails 4, il s'agit d'une meilleure solution (DRYer):
change_column_null :my_models, :date_column, false
Pour vous assurer qu'aucun enregistrement n'existe avec les valeurs NULL
dans cette colonne, vous pouvez passer un quatrième paramètre, qui est la valeur par défaut à utiliser pour les enregistrements avec les valeurs NULL
:
change_column_null :my_models, :date_column, false, Time.now
Rails 4 (other Rails 4 réponses ont des problèmes):
def change
change_column_null(:users, :admin, false, <put a default value here> )
# change_column(:users, :admin, :string, :default => "")
end
La modification d'une colonne contenant des valeurs NULL afin de ne pas autoriser NULL entraînera des problèmes. C’est exactement le type de code qui fonctionnera correctement dans votre configuration de développement, puis se bloquera lorsque vous tenterez de le déployer sur votre [~ # ~] live [~ # ~] production. Vous devez d’abord modifier les valeurs NULL en valeurs valides et , puis interdire les valeurs NULL. La 4ème valeur dans change_column_null
fait exactement cela. Voir documentation pour plus de détails.
En outre, je préfère généralement définir une valeur par défaut pour le champ afin de ne pas avoir besoin de spécifier la valeur du champ à chaque fois que je crée un nouvel objet. J'ai inclus le code commenté pour le faire aussi.
Créez une migration qui a un change_column
déclaration avec un :default =>
valeur.
change_column :my_table, :my_column, :integer, :default => 0, :null => false
Voir: change_column
En fonction du moteur de base de données, vous devrez peut-être utiliser change_column_null
Rails 4:
def change
change_column_null(:users, :admin, false )
end
Dans Rails 4.02 + selon docs il n’existe pas de méthode comme update_all
avec 2 arguments. Au lieu de cela, on peut utiliser ce code:
# Make sure no null value exist
MyModel.where(date_column: nil).update_all(date_column: Time.now)
# Change the column to not allow null
change_column :my_models, :date_column, :datetime, null: false
Vous ne pouvez pas utiliser add_timestamps et null: false si vous avez des enregistrements existants, voici donc la solution:
def change
add_timestamps(:buttons, null: true)
Button.find_each { |b| b.update(created_at: Time.zone.now, updated_at: Time.zone.now) }
change_column_null(:buttons, :created_at, false)
change_column_null(:buttons, :updated_at, false)
end