How to set a default value for a datetime column to record creation time in a migration?

后端 未结 7 665
日久生厌
日久生厌 2020-12-04 13:42

Consider the table creation script below:

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

Is it\'s possible to set

相关标签:
7条回答
  • 2020-12-04 14:17

    If you need to change an existing DateTime column in Rails 5 (rather than creating a new table as specified in other answers) so that it can take advantage of the default date capability, you can create a migration like this:

    class MakeStartsAtDefaultDateForFoo < ActiveRecord::Migration[5.0]
      def change
        change_column :foos, :starts_at, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
      end
    end
    
    0 讨论(0)
  • 2020-12-04 14:20

    You can add a function in a model like this:

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

    So that the model will set the current time in the model.

    You can also place some sql code in the migration for setting the default value at the database level, something like:

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

    Setting something like this:

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

    causes executing the Time.now function during migrating so then the table in database is created like this:

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

    but I think that it is not what you want.

    0 讨论(0)
  • 2020-12-04 14:24

    Active Record automatically timestamps create and update operations if the table has fields named created_at/created_on or updated_at/updated_on. Source - api.rubyonrails.org

    You don't need to do anything else except to have that column.

    0 讨论(0)
  • 2020-12-04 14:33

    This is supported now in Rails 5.

    Here is a sample 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
    

    See discussion at https://github.com/rails/rails/issues/27077 and answer there by prathamesh-sonpatki

    0 讨论(0)
  • 2020-12-04 14:33

    In the answer given by @szymon-lipiński (Szymon Lipiński), the execute method didn't work for me. It was throwing a MySQL syntax error.

    The MySQL syntax which worked for me is this.

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

    So to set the default value for a datetime column in migration script can be done as follows:

    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
    
    0 讨论(0)
  • 2020-12-04 14:35

    I usually do:

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

    So, your schema.rb is going to have something like:

    create_table "your_table", force: :cascade do |t|
      t.datetime "your_column", default: "now()"
    end
    
    0 讨论(0)
提交回复
热议问题