1

我正在使用 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_atschema.rb中的约束。nilnull: 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)
);

为什么不为.createand.new赋值?对于我所有的其他模型,具有相似(但更简单的定义)没有问题。created_atupdated_at

4

1 回答 1

0

我发现我的问题的原因与 SQL 迁移、created_at 或 schema.rb无关validates publication_year, numericality: { only_integer: true, less_than_or_equal_to: Date.today.year() },而是由于在 publication_year 为nil.

刘海头撞墙。

于 2012-07-22T11:05:41.677 回答