Rails迁移生成默认时间戳(created_at,updated_at)为NULLABLE

时间:2014-01-06 18:17:10

标签: ruby-on-rails postgresql activerecord migration jruby

前段时间我们将应用程序升级到 Rails 4 并切换到 JRuby

在此更改之前,迁移会将默认时间戳创建为 NOT NULL 。 在更改之后, NOT NULL 缺失。

我们按如下方式创建这些时间戳(created_at,updated_at):

class Model < ActiveRecord::Migration
  def change
    create_table :model do |t|
      t.belongs_to :user, :null => false

      t.text :content

      t.timestamps
    end
  end
end

我们申请的重要部分是:

  • ruby​​'1.9.3',:engine =&gt; 'jruby',:engine_version =&gt; '1.7.9'
  • gem'trail','4.0.2'
  • gem'activerecord -jdbcpostgresql-adapter','1.3.4'
  • postgresql:stable 9.3.1

您是否知道可能导致问题的原因以及我们如何将默认生成更改回 NOT NULL

2 个答案:

答案 0 :(得分:7)

我不知道它是否记录在任何地方,但the source表示您可以将常用列选项传递给t.timestamps

# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
# <tt>:updated_at</tt> to the table.
def timestamps(*args)
  options = args.extract_options!
  column(:created_at, :datetime, options)
  column(:updated_at, :datetime, options)
end

所以你可以说:

create_table :model do |t|
  #...
  t.timestamps :null => false
end

,你的列应该是NOT NULL。

如果查看3.2 version,您会看到发生了什么:

def timestamps(*args)
  options = { :null => false }.merge(args.extract_options!)
  #...
end

所以3.2默认情况下将timestamp列创建为NOT NULL,但4.0不会。

答案 1 :(得分:0)

这个问题激怒了我,因为我有一个旧的应用程序已经在Rails 3.2上使用了几年,这个方法有很多用法,因此这个初始化程序:

# Force t.timestamps to always be null: false
module ActiveRecord
  module ConnectionAdapters
    class TableDefinition

      def timestamps_with_non_nullable(*args)
        options = args.extract_options!
        options.merge!(null: false)
        timestamps_without_non_nullable(*args, options)
      end
      alias_method_chain :timestamps, :non_nullable

    end
  end
end