私は、SQL(つまりexecute
)を使用してRails 3.2で移行を記述し、データベースレベルでアプリケーションロジック(外部キー、デフォルト、チェック、トリガー)を適用しています。その理由は、異なるアプリケーション(つまり、Railsではない)から同じデータベースを使用したり、データを直接大量にインポートしたりする必要がある場合に備えて、一貫したデータベースの相互作用が必要だからです。1つのモデルのデフォルト値(以下を参照)を除いて、すべてが見事に機能しているようです。
たとえば、created_at
を含めますNOT NULL DEFAULT current_timestamp
。データベースにレコードを作成する場合、これはすべて便利ですが、何らかの理由でschema.rbはデフォルト値を検出しませんが、NOT NULL
制約を正しく識別します。その結果、Model.createまたはModel.new(例BibliographicItem.create(title: "Foo")
)を使用してデータベースにインスタンスを保存できなくなります。これは、schema.rbの制約に違反することになりますcreated_at
。updated_at
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
とに値を.new
割り当てないのはなぜですか?私の他のすべてのモデルでは、同様の(しかしより単純な定義)問題はありません。created_at
updated_at