Agregue una migración de columna de referencia en Rails 4

Un usuario tiene muchas cargas. Quiero agregar una columna a la tabla de uploads que haga referencia al user . ¿Cómo debería ser la migración?

Esto es lo que tengo. No estoy seguro de si debería usar (1) :user_id, :int o (2) :user, :references . Ni siquiera estoy seguro de si (2) funciona. Solo trato de hacer esto de la manera “Rails”.

 class AddUserToUploads < ActiveRecord::Migration def change add_column :uploads, :user_id, :integer end end 

Pregunta relevante a excepción de Rails 3. Rails 3 migrations: ¿Agregar una columna de referencia?

Rails 4.x

Cuando ya tiene users y uploads tablas y desea agregar una nueva relación entre ellas.

Todo lo que necesita hacer es: solo generar una migración usando el siguiente comando:

 rails g migration AddUserToUploads user:references 

Que creará un archivo de migración como:

 class AddUserToUploads < ActiveRecord::Migration def change add_reference :uploads, :user, index: true end end 

Luego, ejecute la migración usando rake db:migrate . Esta migración se ocupará de agregar una nueva columna llamada user_id a la tabla de uploads (haciendo referencia a la columna de id en la tabla de users ), ADEMÁS, también agregará un índice en la nueva columna.

ACTUALIZACIÓN [Para Rails 4.2]

No se puede confiar en que Rails mantenga la integridad referencial; bases de datos relacionales vienen a nuestro rescate aquí. Lo que eso significa es que podemos agregar restricciones de clave externa en el nivel de la base de datos y asegurarnos de que la base de datos rechace cualquier operación que viole esta integridad referencial establecida. Como @infoget comentó, Rails 4.2 se envía con soporte nativo para claves externas (integridad referencial) . No es obligatorio, pero es posible que desee agregar una clave externa (ya que es muy útil) a la referencia que creamos anteriormente.

Para agregar una clave externa a una referencia existente , cree una nueva migración para agregar una clave externa:

 class AddForeignKeyToUploads < ActiveRecord::Migration def change add_foreign_key :uploads, :users end end 

Para crear una referencia completamente nueva con una clave externa (en Rails 4.2) , genere una migración usando el siguiente comando:

 rails g migration AddUserToUploads user:references 

que creará un archivo de migración como:

 class AddUserToUploads < ActiveRecord::Migration def change add_reference :uploads, :user, index: true add_foreign_key :uploads, :users end end 

Esto agregará una nueva clave externa a la columna user_id de la tabla de uploads . La clave hace referencia a la columna de id en la tabla de users .

NOTA: Esto es además de agregar una referencia, por lo que aún necesita crear una referencia primero y luego una clave externa ( puede elegir crear una clave externa en la misma migración o un archivo de migración por separado ). Active Record solo admite claves externas de una sola columna y actualmente solo son compatibles los adaptadores mysql , mysql2 y PostgreSQL . No intente esto con otros adaptadores como sqlite3 , etc. Consulte las Guías de Rails: Llaves foráneas para su referencia.

Carriles 5

Aún puede usar este comando para crear la migración:

 rails g migration AddUserToUploads user:references 

La migración se ve un poco diferente a antes, pero aún funciona:

 class AddUserToUploads < ActiveRecord::Migration[5.0] def change add_reference :uploads, :user, foreign_key: true end end 

Tenga en cuenta que es :user , not :user_id

[Usando Rails 5]

Generar migración:

 rails generate migration add_user_reference_to_uploads user:references 

Esto creará el archivo de migración:

 class AddUserReferenceToUploads < ActiveRecord::Migration[5.1] def change add_reference :uploads, :user, foreign_key: true end end 

Ahora, si observa el archivo de esquema, verá que la tabla de carga contiene un nuevo campo. Algo así como: t.bigint "user_id" o t.integer "user_id" .

Migrar base de datos:

 rails db:migrate 

Otra syntax para hacer lo mismo es:

 rails g migration AddUserToUpload user:belongs_to 

si te gusta otro método alternativo con up método up y down , prueba esto:

  def up change_table :uploads do |t| t.references :user, index: true end end def down change_table :uploads do |t| t.remove_references :user, index: true end end