ruby-on-rails - migrations - type column rails
¿Cómo usar la identificación larga en las aplicaciones de Rails? (11)
Corrección de cómo cambiar el tipo de columna de primary key
predeterminada:
En lugar de:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
deberías hacer:
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = "BIGINT(8) UNSIGNED DEFAULT NULL auto_increment PRIMARY KEY"
de lo contrario, no podrá agregar restricciones de foreign key
en la capa de la base de datos.
¿Cómo puedo cambiar el tipo (predeterminado) para los ID de ActiveRecord? int no es lo suficientemente largo, preferiría mucho tiempo. Me sorprendió que no haya: mucho tiempo para las migraciones: ¿uno solo usa algo de decimal?
Créditos a 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
- Vea la opción
:id => false
que desactiva la creación automática del campo de id. - La línea
t.integer :id, :limit => 8
producirá un campo entero de 64 bits
De acuerdo con la documentación de la API de Rails, las posibles opciones para el tipo son:
:string
:text
:integer
:float
:decimal
:datetime
:timestamp
:time
:date
:binary
:boolean
Puede usar: decimal, o puede ejecutar un comando directamente si necesita:
class MyMigration
def self.up
execute "ALTER TABLE my_table ADD id LONG"
end
end
Como lo señaló wappos, puede usar opciones auxiliares como: limit para decirle a ActiveRecord qué tan grande quiere que sea la columna. Entonces usaría la columna: int con un límite más grande.
En rails4
, puedes hacerlo.
A continuación se muestra un ejemplo para crear un modelo Dummy
en rails4
y 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:
- Utiliza
serial8
como id, que es un entero de 64 bits, y lo define comoprimary key
. - 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.
Escribí una joya llamada activerecord-native_db_types_override que te permite alterar los tipos de datos que se usarán en tus migraciones.
En tu Gemfile, agrega:
gem ''activerecord-native_db_types_override''
luego en config / environment.rb, para usar identificadores largos en postgres, agregue:
NativeDbTypesOverride.configure({
postgres: {
primary_key: { name: "bigserial primary key"}
}
})
Vea su activerecord-native_db_types_override para obtener información actualizada.
Esto es difícil de establecer para la clave principal con migraciones porque Rails la coloca automáticamente.
Puede cambiar cualquier columna más adelante de esta manera:
change_column :foobars, :something_id, ''bigint''
Puede especificar ID no primarios como 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
Donde tengo "letra grande" puede poner cualquier texto que su base de datos usaría para el tipo de columna de base de datos que desea usar (por ejemplo, "largo sin firmar").
Si necesita que su columna de id sea grande, la forma más fácil de hacerlo sería crear la tabla, luego cambie la columna en la misma migración con change_column.
Con PostgreSQL y SQLite, los cambios de esquema son atómicos por lo que esto no dejará su base de datos en un estado extraño si falla la migración. Con MySQL necesitas ser más cuidadoso.
Para establecer el tipo de columna de clave primaria predeterminada , los archivos de migración no son el lugar para meterse.
En cambio, solo 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 se deben crear con el tipo de columna deseado para el id
:
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
Después de que haya hecho lo que se propuso hacer ... la próxima pregunta es, probablemente, "¿Cómo puedo hacer que mis columnas de clave externa tengan el mismo tipo de columna?" ya que no tiene sentido tener personas con clave primaria. ¿ people.id
como bigint(20) unsigned
, y person_id
be int(11)
o cualquier otra cosa?
Para esas columnas, puede consultar las otras sugerencias, por ejemplo
t.column :author_id, ''BIGINT UNSIGNED''
t.integer :author_id, :limit => 8
ACTUALIZACIÓN : @Notinlist, para usar una columna arbitraria para la clave principal en tablas arbitrarias que necesita para realizar la danza create_table-change_column
:
create_table(:users) do |t|
# column definitions here..
end
change_column :users, :id, :float # or some other column type
por ejemplo, si quería guid
lugar de enteros de incremento automático,
create_table(:users, :primary_key => ''guid'') do |t|
# column definitions here..
end
change_column :users, :guid, :string, :limit => 36
Puedes hacerlo así:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users, id: :bigserial do |t|
t.string :name
end
end
end
Rails 3, MySQL:
t.column :foobar, :int, :limit => 8
No me da una letra grande, solo una int. Sin embargo,
t.column :twitter_id, ''bigint''
funciona bien. (Aunque me ata a MySQL.)
Si alguien necesita esto para trabajar con PostgreSQL, crea un inicializador como este:
# config/initializers/bigint_primary_keys.rb
ActiveRecord::Base.establish_connection
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = ''bigserial primary key''
Debido a la carga diferida en Rails 3.2 (y tal vez incluso en versiones anteriores), ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
no será necesario hasta que establezca la conexión a la base de datos.
Tomar prestado de otras soluciones, ajustado por lo que funcionó para mí recientemente.
Agregar a un archivo en config/initializers
. 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 usan una identificación larga son como tales:
create_table :notification_logs, :id => false do |t|
t.column :id, :long_primary_key
# ...
end