ActiveRecord の ID の (デフォルトの) タイプを変更するにはどうすればよいですか? int では十分な長さではありません。長いほうがよいでしょう。移行に :long がないことに驚きました-小数点を使用するだけですか?
11 に答える
http://moeffju.net/blog/using-bigint-columns-in-rails-migrationsのクレジット
class CreateDemo < ActiveRecord::Migration
def self.up
create_table :demo, :id => false do |t|
t.integer :id, :limit => 8
end
end
end
:id => false
id フィールドの自動作成を無効にするオプションを参照してください- 行は
t.integer :id, :limit => 8
64ビット整数フィールドを生成します
デフォルトの主キー列タイプを設定するために、移行ファイルは混乱する場所ではありません。
代わりに、これをあなたの一番下に貼り付けてくださいconfig/environment.rb
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
また、すべてのテーブルは、次の目的の列タイプで作成する必要がありますid
。
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
やろうとしていることを実行した後...次の質問は、おそらく「外部キー列を同じ列タイプにするにはどうすればよいですか?」です。people.id
主キーを as bigint(20) unsigned
、person_id
beなどにするのは意味がないのでint(11)
?
これらの列については、他の提案を参照できます。
t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
更新: @Notinlist、任意のテーブルの主キーに任意の列を使用するには、create_table-change_column
ダンスを行う必要があります。
create_table(:users) do |t|
# column definitions here..
end
change_column :users, :id, :float # or some other column type
たとえばguid
、自動インクリメント整数の代わりに必要な場合は、
create_table(:users, :primary_key => 'guid') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
これは Rails が自動的に設定するため、マイグレーションで主キーに設定するのは困難です。
次のように、後で任意の列を変更できます。
change_column :foobars, :something_id, 'bigint'
次のように、最初の移行で非プライマリ ID をカスタム タイプとして指定できます。
create_table :tweets do |t|
t.column :twitter_id, 'bigint'
t.column :twitter_in_reply_to_status_id, 'bigint'
end
私が "bigint" を持っているところには、データベースが使用したいデータベースの列の型に使用する任意のテキストを入れることができます (例: "unsigned long")。
id 列を bigint にする必要がある場合、それを行う最も簡単な方法は、テーブルを作成してから、同じ移行で change_column を使用して列を変更することです。
PostgreSQL と SQLite では、スキーマの変更はアトミックであるため、移行が失敗してもデータベースが奇妙な状態になることはありません。MySQL では、より注意する必要があります。
Rails API のドキュメントによると、type の可能なオプションは次のとおりです。
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
:decimal を使用するか、必要に応じてコマンドを直接実行できます。
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
wappos が指摘したように、:limit などの補助オプションを使用して、ActiveRecord に列の大きさを指定できます。したがって、より大きな :limit で :int 列を使用します。
PostgreSQL で作業するためにこれが必要な場合は、次のような初期化子を作成します。
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
Rails 3.2 (およびおそらくそれ以前のバージョン) では遅延読み込みActiveRecord::ConnectionAdapters::PostgreSQLAdapter
が行われるため、データベース接続が確立されるまでは必要ありません。
Rails 3、MySQL:
t.column :foobar, :int, :limit => 8
bigint は返されず、int のみが返されます。でも、
t.column :twitter_id, 'bigint'
正常に動作します。(それは私をMySQLに結びつけますが。)
他のソリューションから借りて、最近私のために働いたものに合わせて調整しました。
のファイルに追加しますconfig/initializers
。新しい列タイプを宣言します (chookeat の提案から適応)。
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
長い ID を使用する移行は次のとおりです。
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end
次のように実行できます。
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end
移行で使用されるデータ型を変更できるようにする、 activerecord-native_db_types_overrideという gemを作成しました。
Gemfile に以下を追加します。
gem 'activerecord-native_db_types_override'
次に、config/environment.rb で、postgres で長い ID を使用するには、次を追加します。
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
最新情報については、そのREADMEを参照してください。
primary key
デフォルトの列タイプを変更する方法の修正:
それ以外の:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
やったほうがいい:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
foreign key
そうしないと、データベース層に制限を追加できなくなります。