Migración de carriles para has_and_belongs_to_many join table

¿Cómo hago un script/generate migration para crear una tabla de unión para una relación has_and_belongs_to_many ?

La aplicación se ejecuta en Rails 2.3.2, pero también tengo instalado Rails 3.0.3.

Dónde:

 class Teacher < ActiveRecord::Base has_and_belongs_to_many :students end 

y

 class Student < ActiveRecord::Base has_and_belongs_to_many :teachers end 

para carriles 4:

 rails generate migration CreateJoinTableStudentTeacher student teacher 

para carriles 3:

 rails generate migration students_teachers student_id:integer teacher_id:integer 

para carriles <3

 script/generate migration students_teachers student_id:integer teacher_id:integer 

(tenga en cuenta que el nombre de la tabla enumera ambas tablas de unión en orden alfabético)

y solo para los raíles 3 y siguientes, necesita editar la migración generada para que no se cree un campo de id.

 create_table :students_teachers, :id => false do |t| 

Una tabla has_and_belongs_to_many debe coincidir con este formato. Supongo que los dos modelos a los que se unirá has_and_belongs_to_many ya están en el DB: apples y oranges :

 create_table :apples_oranges, :id => false do |t| t.references :apple, :null => false t.references :orange, :null => false end # Adding the index can massively speed up join tables. Don't use the # unique if you allow duplicates. add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true) 

Si usa el :unique => true en el índice, entonces debería (en rails3) pasar :uniq => true a has_and_belongs_to_many .

Más información: Documentos de Rails

ACTUALIZADO 2010-12-13 Lo he actualizado para eliminar la identificación y las marcas de tiempo … Básicamente, MattDiPasquale y nunopolonia son correctas: no debe haber una identificación y no debe haber marcas de tiempo o los Rails no permitirán que funcione el has_and_belongs_to_many .

Debe nombrar los nombres de los 2 modelos que desea conectar en la tabla por orden alfabético y colocar los dos ID de modelo en la tabla. Luego, conecte cada modelo entre sí creando las asociaciones en el modelo.

Aquí hay un ejemplo:

 # in migration def self.up create_table 'categories_products', :id => false do |t| t.column :category_id, :integer t.column :product_id, :integer end end # models/product.rb has_and_belongs_to_many :categories # models/category.rb has_and_belongs_to_many :products 

Pero esto no es muy flexible y debes pensar en usar has_many: a través de

La respuesta superior muestra un índice compuesto que no creo que se utilizará para buscar manzanas de naranjas.

 create_table :apples_oranges, :id => false do |t| t.references :apple, :null => false t.references :orange, :null => false end # Adding the index can massively speed up join tables. # This enforces uniqueness and speeds up apple->oranges lookups. add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true) # This speeds up orange->apple lookups add_index(:apples_oranges, :orange_id) 

Encontré la respuesta en la que se basa ‘The Doctor What’ útil y la discusión ciertamente también.

En los Rails 4, puedes usarlo fácilmente

create_join_table: table1s,: table2s

esto es todo.

Precaución: debe usar la tabla 1, tabla 2 con alfanumérico.

Me gusta hacer:

rails g migration CreateJoinedTable model1:references model2:references . De esa forma obtengo una migración que se ve así:

 class CreateJoinedTable < ActiveRecord::Migration def change create_table :joined_tables do |t| t.references :trip, index: true t.references :category, index: true end add_foreign_key :joined_tables, :trips add_foreign_key :joined_tables, :categories end end 

Me gusta tener un índice en estas columnas porque a menudo haré búsquedas utilizando estas columnas.