Migrations de rails: annuler le paramètre par défaut d'une colonne


190

J'ai le problème, que j'ai une migration dans Rails qui configure un paramètre par défaut pour une colonne, comme cet exemple:

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

Supposons que j'aime supprimer ces paramètres par défaut lors d'une migration ultérieure, comment puis-je faire cela avec l'utilisation de migrations de rails?

Ma solution de contournement actuelle est l'exécution d'une commande sql personnalisée dans la migration des rails, comme ceci:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

Mais je n'aime pas cette approche, car je dépend maintenant de la façon dont la base de données sous-jacente interprète cette commande. En cas de modification de la base de données, cette requête pourrait ne plus fonctionner et la migration serait interrompue. Alors, existe-t-il un moyen d'exprimer l'annulation d'un paramètre par défaut pour une colonne dans les rails?

Réponses:


387

Rails 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

Rails 3 et Rails 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end

7
Dans postgres, cela ne supprimera pas la valeur par défaut des CHARACTER VARYINGcolonnes, définissez-la simplement sur NULL::character varying.
— Attila O.27

8
Dans les versions plus récentes, vous pouvez le rendre réversible. Par exemple: change_column_default(:table_name, :column_name, from: nil, to: false)
— Mark

1
@AttilaO. J'ai eu du succès à courir ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, pas besoin de le régler NULLje pense.
— Eli Rose - REINSTATE MONICA

Pour info, il semble que la version réversible mentionnée par @Mark a été ajoutée dans Rails 5+, donc tout ce qui est en dessous, vous ne pourrez pas l'utiliser.
— Joshua Pinter

23

On dirait que vous faites la bonne chose avec votre 'exécution', comme le soulignent les documents:

change_column_default(table_name, column_name, default)

Définit une nouvelle valeur par défaut pour une colonne. Si vous souhaitez définir la valeur par défaut sur NULL, vous n'avez pas de chance. Vous devez DatabaseStatements # exécuter vous-même l'instruction SQL appropriée. Exemples

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)

Merci! Je n'ai pas trouvé cet indice dans la documentation par moi-même! Espérons qu'ils intègrent la suppression des valeurs par défaut dans les migrations dans les futures versions de rails.
— wulfovitch

1
Ce n'est plus vrai depuis Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
— asymétrique

14

L'extrait suivant que j'utilise pour créer des NULLcolonnes NOT NULL, mais ignorer DEFAULTau niveau du schéma:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end

Je ne vois pas de valeur ajoutée dans cette réponse puisque celle acceptée déclare la même chose.
— Mosselman

-3

Rails 4

change_column :courses, :name, :string, limit: 100, null: false

10
Celui-ci ajoute la contrainte NOT NULL, cela n'a rien à voir avec DEFAULT
— Extrapolator

n'a rien à voir avec DEFAULT +1
— Ivan Wang
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.