Как использовать длинный идентификатор в приложениях Rails?
-
21-08-2019 - |
Вопрос
Как я могу изменить тип (по умолчанию) идентификаторов ActiveRecord?int недостаточно длинный, я бы предпочел long.Я был удивлен, что для миграций нет :long - можно ли просто использовать какое-то десятичное число?
Решение
Кредиты для 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
как bigint(20) unsigned
, и person_id
быть 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'
Вы можете указать неосновные идентификаторы в качестве пользовательских типов при первоначальной миграции следующим образом:
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, какого размера вы хотите, чтобы столбец был.Таким образом, вы бы использовали столбец:int с большим значением :limit.
Если кому-то это нужно для работы с 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
не потребуется до тех пор, пока вы не установите соединение с базой данных.
В rails4
, ты можешь это сделать.
Ниже приведен пример создания Dummy
модель в rails4
& postgres
,
xxx_migrate_dummies.rb:
class CreateDummies < ActiveRecord::Migration
def change
create_table :dummies, :id => false do |t|
t.column :id, :serial8, primary_key: true
t.string :name, :limit => 50, null: false
t.integer :size, null: false
t.column :create_date, :timestamptz, null: false
end
end
end
Что он сделал:
- Это использование
serial8
как тип идентификатора, который является 64-битным целым числом, и определите его какprimary key
. - Это использование
timestamptz
как тип datetime, который содержит информацию о часовом поясе, это важно для приложения, которое работает в нескольких часовых поясах.
Rails 3, MySQL:
t.column :foobar, :int, :limit => 8
Не дает мне большого значения, только 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"
Миграции, использующие длинный идентификатор, являются таковыми:
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end
Я написал жемчужину под названием activerecord-native_db_types_override-исходный код_db_types_override это позволяет вам изменять типы данных, которые будут использоваться при ваших миграциях.
В вашем Gemfile добавьте:
gem 'activerecord-native_db_types_override'
затем в config/environment.rb, чтобы использовать длинные идентификаторы в postgres, добавьте:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
Увидеть его ПРОЧИТАЙ МЕНЯ для получения актуальной информации.
Вы можете сделать это вот так:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end
Исправление к тому, как изменить значение по умолчанию 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
ограничения на уровне базы данных.