8

我使用它的常用方式是

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

4 回答 4

13

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

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

在 Postgresql 修饰符中产生类似的东西

not null default now()
于 2016-10-21T04:27:06.023 回答
8

你的问题和答案让我走了。使用 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(),
于 2015-12-16T01:44:19.400 回答
2

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

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

所以谢谢!

于 2013-06-09T08:09:19.477 回答
-7

实现此目的的正确/干净/整洁的方法是使用此迁移:

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

因此,您有:

  • 标准迁移,没有特定的 sql 命令会引发 IrreversibleMigration。
  • 使用时区设置当前时间戳的标准 postgresql 方法
  • 在应用程序级别不需要触发器/过滤器:查看 Transaction.new.date 的输出
  • 与 mysql 等其他 RDBMS 一起使用
于 2013-10-08T17:51:32.963 回答