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?

wulfovitch
la source

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
Jeremy Mack
la source
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)
Serx
la source
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
Alex Fortuna
la source
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
Lesly Revenge
la source
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