Rails无法使用NOW()默认值创建迁移到Postgres

时间:2013-06-08 14:44:02

标签: ruby-on-rails postgresql timestamp migration

我使用它的常用方法是

psql > ALTER TABLE transactions ALTER COLUMN date SET DEFAULT CURRENT_TIMESTAMP\g

它工作正常。

在我的RoR应用程序中,我试图以两种方式创建迁移。

1

class TransactionsSetDefaultDateChange < ActiveRecord::Migration
  change_column :transactions, :date, :datetime, :null=>false, :default=>'CURRENT_TIMESTAMP'
end

2

class TransactionsSetDefaultDateChange < ActiveRecord::Migration
 execute <<-SQL
    ALTER TABLE transactions ALTER COLUMN date SET DEFAULT CURRENT_TIMESTAMP
 SQL
end

都失败了。有什么想法吗?

PS这种情况适用于迁移(“rake db:migrate”),但未在“rake db:setup”上正确应用(丢失SQL语句)

class TransactionsSetDefaultDateChange < ActiveRecord::Migration
 def change
 execute <<-SQL
    ALTER TABLE transactions ALTER COLUMN date SET DEFAULT CURRENT_TIMESTAMP
 SQL
 end
end

4 个答案:

答案 0 :(得分:9)

对于Rails 5+,现在可以使用

... null: false, default: -> { 'NOW()' } ...

在Postgresql Modifiers中生成类似的内容

not null default now()

答案 1 :(得分:7)

你的问题和答案让我走了。使用Rails 4.2.4和Postgres 9.3,以下迁移代码对我有用:

    create_table :goodies do |t|
      t.datetime :last_read_at, null: false
    end
    execute "ALTER TABLE goodies ALTER COLUMN last_read_at SET DEFAULT CURRENT_TIMESTAMP"

它产生了一个有效的SQL:

    last_read_at timestamp without time zone NOT NULL DEFAULT now(),

答案 2 :(得分:2)

当然我们可以在postgres中完成。用current_timestamp查看我的例子。它使用“default NOW()”创建列。奇怪的是,rails AR不支持这样的核心功能。但这不是重点。解决方案是以这种方式修复模型

before_create :record_date 
protected 
def record_date 
    self.date = read_attribute(:date) || Time.now 
end 

所以,谢谢!

答案 3 :(得分:-7)

通过此迁移实现此目的的正确/清洁/整洁方式:

class TransactionsSetDefaultDateChange < ActiveRecord::Migration
  change_column :transactions, :date, :datetime, :null=>false, :default=>'now()'
end

因此,你有:

  • 标准迁移,没有引发IrreversibleMigration的特定sql命令。
  • 使用timezone设置当前时间戳的标准postgresql方法
  • 在应用程序级别不需要触发器/过滤器:查看Transaction.new.date的输出
  • 与其他RDBMS(如mysql)一起使用