Comment définir la valeur par défaut pour une colonne datetime dans le script de migration?

Considérez le script de création de table ci-dessous:

create_table :foo do |t| t.datetime :starts_at, :null => false end 

Est-il possible de définir la valeur par défaut comme l’heure actuelle?

J’essaie de trouver un équivalent indépendant de la firebase database dans les rails pour les définitions de colonne SQL ci-dessous:

Syntaxe Oracle

 start_at DATE DEFAULT SYSDATE() 

MySQL Syntaxe

 start_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 

OU

 start_at DATETIME DEFAULT NOW() 

Ceci est supporté maintenant dans Rails 5.

Voici un exemple de migration:

 class CreatePosts < ActiveRecord::Migration[5.0] def change create_table :posts do |t| t.datetime :modified_at, default: -> { 'CURRENT_TIMESTAMP' } t.timestamps end end end 

Voir la discussion sur https://github.com/rails/rails/issues/27077 et y répondre par prathamesh-sonpatki

Vous pouvez append une fonction dans un modèle comme celui-ci:

  before_create :set_foo_to_now def set_foo_to_now self.foo = Time.now end 

Pour que le modèle définisse l’heure actuelle dans le modèle.

Vous pouvez également placer du code SQL dans la migration pour définir la valeur par défaut au niveau de la firebase database, par exemple:

 execute 'alter table foo alter column starts_at set default now()' 

Mettre quelque chose comme ça:

 create_table :foo do |t| t.datetime :starts_at, :null => false, :default => Time.now end 

provoque l’exécution de la fonction Time.now lors de la migration afin que la table dans la firebase database soit créée comme ceci:

 create table foo ( starts_at timestamp not null default '2009-01-01 00:00:00'); 

mais je pense que ce n’est pas ce que vous voulez.

Si vous avez une colonne datetime appelée created_at ou created_on , ActiveRecord la définira comme par magie à la date / heure de création. Vous n’avez rien d’autre à faire que d’avoir cette colonne.

Vous pouvez également avoir updated_at ou updated_on et il sera mis à jour lorsqu’un enregistrement est mis à jour.

Je cherchais une solution similaire mais j’ai fini par utiliser https://github.com/FooBarWidget/default_value_for .

Le plugin default_value_for permet de définir les valeurs par défaut des modèles ActiveRecord de manière déclarative. Par exemple:

 class User < ActiveRecord::Base default_value_for :name, "(no name)" default_value_for :last_seen do Time.now end end u = User.new u.name # => "(no name)" u.last_seen # => Mon Sep 22 17:28:38 +0200 2008 

Je fais habituellement:

 def change execute(" ALTER TABLE your_table ALTER COLUMN your_column SET DEFAULT CURRENT_TIMESTAMP ") end 

Donc, votre schema.rb va avoir quelque chose comme:

 create_table "your_table", force: :cascade do |t| t.datetime "your_column", default: "now()" end 

Si vous devez modifier une colonne DateTime existante dans Rails 5 (plutôt que de créer une nouvelle table comme spécifié dans d’autres réponses) afin de tirer parti de la fonctionnalité de date par défaut, vous pouvez créer une migration comme celle-ci:

 class MakeStartsAtDefaultDateForFoo < ActiveRecord::Migration[5.0] def change change_column :foos, :starts_at, :datetime, default: -> { 'CURRENT_TIMESTAMP' } end end 

Sur les rails 5.1

 class CreateClients < ActiveRecord::Migration[5.1] def change create_table :cars do |t| ******************************* t.datetime :starts_at, :null => false, default: -> {'CURRENT_TIMESTAMP'} ******************************* t.timestamps end end end 

Dans la réponse donnée par @ szymon-lipiński (Szymon Lipiński), la méthode d’exécution n’a pas fonctionné pour moi. Il y avait une erreur de syntaxe MySQL.

La syntaxe MySQL qui a fonctionné pour moi est la suivante.

 execute "ALTER TABLE mytable CHANGE `column_name` `column_name` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" 

Ainsi, pour définir la valeur par défaut d’une colonne datetime dans le script de migration, procédez comme suit:

 def up create_table :foo do |t| t.datetime :starts_at, :null => false end execute "ALTER TABLE `foo` CHANGE `starts_at` `starts_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" end