Как использовать длинный идентификатор в приложениях Rails?

StackOverflow https://stackoverflow.com/questions/1066340

Вопрос

Как я могу изменить тип (по умолчанию) идентификаторов 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 ограничения на уровне базы данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top