Risposte:
Dove:
class Teacher < ActiveRecord::Base
has_and_belongs_to_many :students
end
e
class Student < ActiveRecord::Base
has_and_belongs_to_many :teachers
end
per binari 4:
rails generate migration CreateJoinTableStudentTeacher student teacher
per binari 3:
rails generate migration students_teachers student_id:integer teacher_id:integer
per binari <3
script/generate migration students_teachers student_id:integer teacher_id:integer
(nota che il nome della tabella elenca entrambe le tabelle di join in ordine alfabetico)
e quindi solo per rails 3 e inferiori, è necessario modificare la migrazione generata in modo che non venga creato un campo id:
create_table :students_teachers, :id => false do |t|
rails generate migration CreateJoinTableTeacherStudent teacher student
invece rails generate migration CreateJoinTableStudentTeacher student teacher
, è lo stesso? S (tudent) deve prima di T (eacher)?
Una has_and_belongs_to_many
tabella deve corrispondere a questo formato. Presumo che i due modelli a cui unirsi has_and_belongs_to_many
siano già nel 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 usi l' :unique => true
indice, dovresti (in rails3) passare :uniq => true
a has_and_belongs_to_many
.
Ulteriori informazioni: Rails Docs
AGGIORNATO 2010-12-13 L'ho aggiornato per rimuovere id e timestamp ... Fondamentalmente MattDiPasquale
e nunopolonia
sono corretti: non deve esserci un id e non devono esserci timestamp o rails non permetteranno has_and_belongs_to_many
di funzionare.
script/generate migration
...
È necessario denominare la tabella con i nomi dei 2 modelli che si desidera collegare in ordine alfabetico e inserire i due ID modello nella tabella. Quindi connetti ogni modello tra loro creando le associazioni nel modello.
Ecco un esempio:
# 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
Ma questo non è molto flessibile e dovresti pensare di usare has_many: through
La risposta in alto mostra un indice composito che non credo verrà utilizzato per cercare le mele dalle arance.
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)
Ho trovato utile la risposta su cui si basa "The Doctor What" e certamente lo è anche la discussione.
In rails 4, puoi un utilizzo semplice
create_join_table: table1s,: table2s
è tutto.
Attenzione: è necessario offordinare table1, table2 con caratteri alfanumerici.
Mi piace fare:
rails g migration CreateJoinedTable model1:references model2:references
. In questo modo ottengo una migrazione simile a questa:
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
Mi piace avere indice su queste colonne perché spesso farò ricerche utilizzando queste colonne.
add_foreign_key
fallirà se inserito nella stessa migrazione di quella che ha creato le tabelle.