¿Cómo utilizar una identificación larga en aplicaciones Rails?
-
21-08-2019 - |
Pregunta
¿Cómo puedo cambiar el tipo (predeterminado) de las ID de ActiveRecord?int no es lo suficientemente largo, preferiría mucho tiempo.Me sorprendió que no haya mucho tiempo para las migraciones. ¿Se usa simplemente algún decimal?
Solución
http://moeffju.net/blog/using- bigint-columnas-en-carril-migraciones
class CreateDemo < ActiveRecord::Migration
def self.up
create_table :demo, :id => false do |t|
t.integer :id, :limit => 8
end
end
end
- Consulte la opción
:id => false
que desactiva la creación automática de campo id - La línea
t.integer :id, :limit => 8
producirá un campo entero de 64 bits
Otros consejos
Para configurar el tipo de columna de clave principal predeterminada, los archivos de migración no son el lugar para meterse con ellos.
En lugar de eso, simplemente pega esto en la parte inferior de tu config/environment.rb
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
Y todas sus tablas deben crearse con el tipo de columna previsto para id
:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
Después de haber hecho lo que te propusiste hacer...La siguiente pregunta es probablemente "¿Cómo hago que mis columnas de clave extranjera sean el mismo tipo de columna?" Dado que no tiene sentido tener una clave principal people.id
como bigint(20) unsigned
, y person_id
ser int(11)
¿O algo más?
Para esas columnas, puede consultar las otras sugerencias, p.
t.column :author_id, 'BIGINT UNSIGNED'
t.integer :author_id, :limit => 8
ACTUALIZAR:@Notinlist, para usar una columna arbitraria para la clave principal en tablas arbitrarias, debe hacer lo siguiente create_table-change_column
bailar:
create_table(:users) do |t|
# column definitions here..
end
change_column :users, :id, :float # or some other column type
p.ej.si quisiera guid
en lugar de números enteros de incremento automático,
create_table(:users, :primary_key => 'guid') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
Esto es difícil de establecer para la clave principal con las migraciones porque Rails pone en forma automática.
Puede cambiar cualquiera de las columnas más adelante como esto:
change_column :foobars, :something_id, 'bigint'
Se pueden especificar identificadores no primarios como los tipos personalizados en su migración inicial de esta manera:
create_table :tweets do |t|
t.column :twitter_id, 'bigint'
t.column :twitter_in_reply_to_status_id, 'bigint'
end
Cuando tengo "BIGINT" se puede poner cualquier texto que su base de datos usaría para el tipo de columna de base de datos que desea utilizar (por ejemplo, "unsigned long").
Si necesita que su columna id para ser un bigint, la forma más fácil de hacerlo sería la creación de la tabla, a continuación, cambiar la columna en la misma migración con change_column.
Con PostgreSQL y SQLite, los cambios en el esquema son atómicas así que esto no va a dejar su base de datos en un estado extraño si falla la migración. Con MySQL tiene que ser más cuidadoso.
De acuerdo con la documentación de la API rieles, las posibles opciones de tipo son:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
Puede utilizar: decimal, o puede ejecutar un comando directamente si es necesario:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
Como wappos señalaron, puede utilizar las opciones auxiliares como: límite para contar ActiveRecord lo grande que desea que la columna sea. Así se usaría el: int columna con una más grande:. Límite
Si alguien necesita esto para trabajar con PostgreSQL, crear un inicializador de esta manera:
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key'
No se requerirá Debido a la carga diferida en Rails 3.2 (y versiones anteriores) tal vez incluso, ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
hasta que se establezca la conexión de base de datos.
En rails4
, puedes hacerlo.
A continuación se muestra un ejemplo para crear un Dummy
modelo en 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
Qué hizo:
- se utiliza
serial8
como tipo de identificación, que es un entero de 64 bits, y lo define comoprimary key
. - se utiliza
timestamptz
como tipo de fecha y hora, que contiene la información de la zona horaria, esto es importante para una aplicación que atraviesa varias zonas horarias.
Rails 3, MySQL:
t.column :foobar, :int, :limit => 8
Lo que no me dará un bigint, solamente un int. Sin embargo,
t.column :twitter_id, 'bigint'
funciona bien. (A pesar de que hace atarme a MySQL.)
Préstamos de otras soluciones, ajustado por lo que funcionó para mí recientemente.
Añadir a un archivo en config/initializers
. Se declara un nuevo tipo de columna (adaptado de la sugerencia de chookeat).
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:long_primary_key] = "BIGINT(20) DEFAULT NULL auto_increment PRIMARY KEY"
Las migraciones que utilizan un largo Identificación son como tal:
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end
Me escribió una gema llamada activerecord-native_db_types_override que le permite alterar los tipos de datos que se utilizarán en sus migraciones.
En su Gemfile, añadir:
gem 'activerecord-native_db_types_override'
A continuación, en config / environment.rb, para utilizar los identificadores largos en Postgres, añadir:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
Consulte el README de información puesta al día.
Puede hacerlo de esta manera:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end
Corrección de cómo cambiar el tipo de columna primary key
por defecto:
En lugar de:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
que debe hacer:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
o de lo contrario no será capaz de añadir foreign key
restricciones en la capa de base de datos.