2011-02-10 25 views
158

Si creo un nuevo carriles 3 de migración con (por ejemplo)Rails 3 migraciones: ¿Agregar una columna de referencia?

rails g migration tester title:tester user:references 

, todo funciona bien ... sin embargo si añado una columna con algo en la línea de:

rails g migration add_user_to_tester user:references 

la el campo de referencia no es reconocido En resumen, la pregunta es: ¿cómo agrego una columna de referencia a una migración de rieles desde la línea de comando?

Respuesta

203

Si está utilizando los carriles 4 .x ahora puede generar migraciones con referencias, así:

rails generate migration AddUserRefToProducts user:references 

como se puede ver en rails guides

+1

Consulte la sección 2.1 de http://edgeguides.rubyonrails.org/active_record_migrations.html, por ejemplo. –

+2

¿cómo se especifica un nombre de columna para la clave externa en lugar del nombre generado automáticamente? –

+0

@jwill puede usar polimórficos: usuario: referencias {polimórficos}. –

186

EDITAR: Esta es una respuesta obsoleta y no debe ser aplicado para rieles 4.x +

No es necesario añadir referencias cuando se puede utilizar un identificador de número entero a su clase de referencia.

Yo diría que la ventaja de usar referencias en lugar de un entero simple es que el modelo estará predefinido con belongs_to y dado que el modelo ya está creado y no se verá afectado cuando migre algo existente, el propósito es perdió.

Así que me gustaría hacer como esto en su lugar:

rails g migration add_user_id_to_tester user_id:integer 

Y luego añadir manualmente belongs_to: usuario en el modelo probador

+9

Pero eso no va a crear las restricciones de clave externa correspondientes en las bases de datos que lo apoyan, ¿verdad? – abahgat

+19

No, afaik Rails nunca crea restricciones de claves externas en la base de datos a menos que agregue complementos para hacerlo por usted. – DanneManne

+0

solo estudiando esta publicación, pls cómo agrego la referencia después de todo –

100

Tenga en cuenta que lo más probable es que tenga un índice en esa columna también.

class AddUserReferenceToTester < ActiveRecord::Migration 
    def change 
    add_column :testers, :user_id, :integer 
    add_index :testers, :user_id 
    end 
end 
+1

¿Por qué? ¿Es esto cierto para la mayoría de las relaciones de belongs_to? – ahnbizcad

+1

@gwho creo que es por razones de rendimiento – Darbs

+0

Es de hecho por razones de rendimiento y es útil si tienes un has_many/has_one en el otro lado de esa relación belongs_to. Si está absolutamente seguro de que no pasará por 'user.testers' puede omitir el índice. – Eugene

8

Al agregar una columna que necesita para hacer que la columna un número entero y si es posible con el palo de convenciones carriles. Entonces, para su caso, supongo que ya tiene un Tester y modelos de usuario, y tablas de probadores y usuarios.

Para agregar la clave externa que necesita para crear una columna entera con el nombre user_id (convención):

add_column :tester, :user_id, :integer 

continuación, agregar un belongs_to al modelo probador:

class Tester < ActiveRecord::Base 
    belongs_to :user 
end 

y es posible que también desea agregar un índice para la clave externa (esto es algo que las referencias ya le hacen):

add_index :tester, :user_id 
50

Con los dos pasos anteriores indicados anteriormente, aún falta la restricción de clave externa. Esto debería funcionar:

class AddUserReferenceToTester < ActiveRecord::Migration 
     def change 
      add_column :testers, :user_id, :integer, references: :users 
     end 
    end 
+0

Esta es la única respuesta real aquí. La clave foránea es la parte más importante aquí. – user2490003

+0

. Esta debe marcarse como la respuesta correcta, ya que las preguntas requieren rieles. 3 –

3

Puede añadir referencias a su modelo a través de línea de comandos de la siguiente manera:

rails g migration add_column_to_tester user_id:integer 

Esto generará un archivo de migración como:

class AddColumnToTesters < ActiveRecord::Migration 
    def change 
    add_column :testers, :user_id, :integer 
    end 
end 

Esto funciona bien cada vez que lo uso ..

35

Usted puede usar referencias en una migración de cambio. Esto es válido rieles 3.2.13 código:

class AddUserToTester < ActiveRecord::Migration 
    def change 
    change_table :testers do |t| 
     t.references :user, index: true 
    end 
    end 
    def down 
    change_table :testers do |t| 
     t.remove :user_id 
    end 
    end 
end 

cf: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table

+1

¿cambiar y bajar métodos? no son métodos arriba y abajo en su lugar? – MaicolBen

+0

@MaicolBen sí, y también puede dejar el método de abajo. – Hut8

+0

@MaicolBen sin el método 'down', tengo' ActiveRecord :: IrreversibleMigration' al rodar hacia atrás usando Rails 3.2. También tuve que cambiar 'change' por' up'. –

8

que va a hacer el truco:

rails g migration add_user_to_tester user_id:integer:index 
+0

Me gusta que esto también agregue el índice que probablemente querrá. – bheeshmar

27

Correr rails g migration AddUserRefToSponsors user:references generará la siguiente migración:

def change 
    add_reference :sponsors, :user, index: true 
end 
+0

¿Para qué versión de Rails es esto? –

3

Para rieles 4

El generador acepta el tipo de columna como referencias (también disponible como belongs_to).

Esta migración creará un user_id columna y el índice apropiado:

$ rails g migration AddUserRefToProducts user:references 

genera:

class AddUserRefToProducts < ActiveRecord::Migration 
    def change 
    add_reference :products, :user, index: true 
    end 
end 

http://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

para los carriles 3

Helper se llama referencias (también disponible como belongs_to).

Esta migración creará una columna category_id del tipo apropiado. Tenga en cuenta que pasa el nombre del modelo, no el nombre de la columna. Active Record agrega el _id por usted.

change_table :products do |t| 
    t.references :category 
end 

Si tiene polimórficos belongs_to asociaciones continuación referencias añadirán las dos columnas necesarias:

change_table :products do |t| 
    t.references :attachment, :polymorphic => {:default => 'Photo'} 
end 

a añadir una columna attachment_id y una columna de cadena attachment_type con un valor por defecto de Photo.

http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration

Cuestiones relacionadas