我正在使用 SQL(即execute
)在 Rails 3.2 中编写迁移,以在数据库级别强制执行应用程序逻辑(外键、默认值、检查、触发器)。原因是我想要一致的数据库交互,以防我需要使用来自不同应用程序(即不是 Rails)的相同数据库或直接大量导入数据。除了一个模型的默认值(见下文)之外,一切似乎都工作得很好。
例如created_at
将包括NOT NULL DEFAULT current_timestamp
. 如果我在数据库中创建一条记录,这一切都很好,但由于某种原因,schema.rb 没有检测到默认值,但正确地识别了NOT NULL
约束。结果是我无法使用 Model.create 或 Model.new(例如BibliographicItem.create(title: "Foo")
)将实例保存在数据库中,因为created_at
最终违反了updated_at
schema.rb中的约束。nil
null: false
schema.rb 中的违规表:
create_table "bibliographic_items", :id => false, :force => true do |t|
t.string "uuid", :limit => nil, :null => false
t.string "title", :limit => nil, :null => false
t.integer "publication_year"
t.string "type", :limit => nil, :null => false
t.text "description"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
其型号:
class BibliographicItem < ActiveRecord::Base
include Extensions::UUID
attr_accessible :title, :publication_year, :description
has_many :authorships
has_many :authors, through: :authorships, order: "role DESC, author_order DESC NULLS LAST"
validates :title, presence: true, length: { maximum: 500 }
validates :publication_year, numericality: { only_integer: true,
less_than_or_equal_to: Date.today.year() }
end
语句中的表创建execute
:
CREATE TABLE bibliographic_items (
uuid uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
title varchar NOT NULL,
publication_year int CHECK (publication_year <= left(now()::text, 4)::int),
type varchar NOT NULL REFERENCES bibliographic_item_types ON UPDATE CASCADE ON DELETE RESTRICT,
description text,
created_at timestamp without time zone NOT NULL DEFAULT current_timestamp,
updated_at timestamp without time zone NOT NULL DEFAULT current_timestamp,
CHECK (updated_at >= created_at)
);
为什么不为.create
and.new
赋值?对于我所有的其他模型,具有相似(但更简单的定义)没有问题。created_at
updated_at