Подтвердить что ты не робот

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

Как я могу изменить тип (по умолчанию) для идентификаторов ActiveRecord? int не достаточно длинный, я бы предпочел бы долго. Я был удивлен, что нет: долго для миграции - используется ли какой-нибудь десятичный знак?

4b9b3361

Ответ 1

Кредиты 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-битное целочисленное поле

Ответ 2

Чтобы установить тип столбца по умолчанию для первичного ключа по умолчанию, файлы миграции не являются местом для беспорядка.

Вместо этого просто придерживайтесь этого в нижней части 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 be int(11) или что-нибудь еще?

Для этих столбцов вы можете ссылаться на другие предложения, например

t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8

UPDATE: @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

Ответ 3

Трудно установить первичный ключ с миграциями, потому что 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 был большим, самым простым способом было бы создать таблицу, а затем изменить столбец в той же миграции с помощью change_column.

С PostgreSQL и SQLite изменения схемы являются атомарными, поэтому это не приведет к тому, что ваша база данных окажется в странном состоянии, если сбой миграции. С MySQL вам нужно быть более осторожным.

Ответ 4

В соответствии с документацией API Rails возможные варианты для типа:

: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 с большим лимитом.

Ответ 5

Если кому-то это нужно для работы с 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 не потребуется, пока вы не установите соединение с базой данных.

Ответ 6

В 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 как тип id, который является 64-битным целым числом и определяет его как primary key.
  • Он использует timestamptz как тип даты, который содержит информацию о часовом поясе, это важно для приложения, которое использует несколько часовых поясов.

Ответ 7

Rails 3, MySQL:

t.column :foobar, :int, :limit => 8

Не дает мне bigint, только int. Тем не менее,

t.column :twitter_id, 'bigint'

работает отлично. (Хотя он привязывает меня к MySQL.)

Ответ 8

Заимствование из других решений, скорректированное на то, что сработало для меня в последнее время.

Добавьте в файл 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

Ответ 9

Я написал драгоценный камень под названием activerecord-native_db_types_override, который позволяет вам изменять типы данных, которые будут использоваться в ваших миграциях.

В своем Gemfile добавьте:

gem 'activerecord-native_db_types_override'

затем в config/environment.rb, чтобы использовать длинные идентификаторы в postgres, добавьте:

NativeDbTypesOverride.configure({
  postgres: {
    primary_key: { name: "bigserial primary key"}
  }
})

Обратитесь к README для получения актуальной информации.

Ответ 10

Вы можете сделать это следующим образом:

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users, id: :bigserial do |t|
      t.string :name
    end
  end
end

Ответ 11

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