Respostas:
Onde:
class Teacher < ActiveRecord::Base
has_and_belongs_to_many :students
end
e
class Student < ActiveRecord::Base
has_and_belongs_to_many :teachers
end
para trilhos 4:
rails generate migration CreateJoinTableStudentTeacher student teacher
para trilhos 3:
rails generate migration students_teachers student_id:integer teacher_id:integer
para trilhos <3
script/generate migration students_teachers student_id:integer teacher_id:integer
(observe que o nome da tabela lista as duas tabelas de junção em ordem alfabética)
e somente para os trilhos 3 e abaixo, é necessário editar a migração gerada para que um campo de ID não seja criado:
create_table :students_teachers, :id => false do |t|
rails generate migration CreateJoinTableTeacherStudent teacher student
vez de rails generate migration CreateJoinTableStudentTeacher student teacher
, é o mesmo? S (tudent) precisa antes de T (eacher)?
Uma has_and_belongs_to_many
tabela deve corresponder a este formato. Estou assumindo que os dois modelos aos quais se juntam has_and_belongs_to_many
já estão no DB: apples
e 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)
Se você usar o :unique => true
no índice, deverá (no rails3) passar :uniq => true
para has_and_belongs_to_many
.
Mais informações: Rails Docs
ATUALIZADO 13-12-2010 Atualizei-o para remover a identificação e os carimbos de data e hora ... Basicamente, MattDiPasquale
e nunopolonia
estão corretos: não deve haver um ID e não deve haver carimbos de data e hora ou os trilhos não permitirão has_and_belongs_to_many
funcionar.
script/generate migration
...
Você deve nomear na tabela os nomes dos 2 modelos que deseja conectar por ordem alfabética e colocar os dois IDs de modelo na tabela. Em seguida, conecte cada modelo um ao outro, criando as associações no modelo.
Aqui está um exemplo:
# 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
Mas isso não é muito flexível e você deve pensar em usar has_many: através
A resposta superior mostra um índice composto que não acredito que será usado para procurar maçãs de laranjas.
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)
Eu encontrei a resposta em que isso é baseado em 'The Doctor What' útil e a discussão certamente também.
Nos trilhos 4, você pode usar de maneira simples
create_join_table: table1s,: table2s
isso é tudo.
Cuidado: você deve oferecer tabela1, tabela2 com alfanumérico.
Eu gosto de fazer:
rails g migration CreateJoinedTable model1:references model2:references
. Dessa forma, recebo uma migração parecida com esta:
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
Eu gosto de ter um índice nessas colunas, porque frequentemente faço pesquisas usando essas colunas.
add_foreign_key
falhará se colocado na mesma migração que a que criou as tabelas.