Réponses:
Où:
class Teacher < ActiveRecord::Base
has_and_belongs_to_many :students
end
et
class Student < ActiveRecord::Base
has_and_belongs_to_many :teachers
end
pour les rails 4:
rails generate migration CreateJoinTableStudentTeacher student teacher
pour les rails 3:
rails generate migration students_teachers student_id:integer teacher_id:integer
pour rails <3
script/generate migration students_teachers student_id:integer teacher_id:integer
(notez que le nom de la table répertorie les deux tables de jointure par ordre alphabétique)
puis pour les rails 3 et inférieurs uniquement, vous devez modifier votre migration générée afin qu'aucun champ d'identifiant ne soit créé:
create_table :students_teachers, :id => false do |t|
rails generate migration CreateJoinTableTeacherStudent teacher student
au lieu de rails generate migration CreateJoinTableStudentTeacher student teacher
, c'est pareil? S (tudent) doit-il avant T (eacher)?
Un has_and_belongs_to_many
tableau doit correspondre à ce format. Je suppose que les deux modèles à rejoindre has_and_belongs_to_many
sont déjà dans la base de données: apples
et 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 vous utilisez le :unique => true
sur l'index, vous devez (dans rails3) passer :uniq => true
à has_and_belongs_to_many
.
Plus d'informations: Rails Docs
MISE À JOUR 13/12/2010 Je l'ai mis à jour pour supprimer l'id et les horodatages ... Fondamentalement MattDiPasquale
et nunopolonia
sont corrects: il ne doit pas y avoir d'id et il ne doit pas y avoir d'horodatage ou les rails ne permettent pas has_and_belongs_to_many
de fonctionner.
script/generate migration
...
Vous devez nommer le tableau avec les noms de 2 modèles que vous souhaitez connecter par ordre alphabétique et mettre les deux identifiants de modèle dans le tableau. Ensuite, connectez chaque modèle les uns aux autres en créant les associations dans le modèle.
Voici un exemple:
# 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
Mais ce n'est pas très flexible et vous devriez penser à utiliser has_many: through
La réponse du haut montre un index composite qui, je ne pense pas, sera utilisé pour rechercher des pommes à partir d'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.
# 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)
J'ai trouvé la réponse sur laquelle est basée «The Doctor What» utile et la discussion aussi certainement.
Dans les rails 4, vous pouvez utiliser simplement
create_join_table: table1s,: table2s
c'est tout.
Attention: vous devez offord table1, table2 avec alphanumérique.
J'aime faire:
rails g migration CreateJoinedTable model1:references model2:references
. De cette façon, j'obtiens une migration qui ressemble à ceci:
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
J'aime avoir un index sur ces colonnes car je vais souvent faire des recherches en utilisant ces colonnes.
add_foreign_key
échouera s'il est placé dans la même migration que celle qui a créé les tables.