Comment faire un script/generate migration
pour créer une table de jointure pour un has_and_belongs_to_many
relation?
L'application s'exécute sur Rails 2.3.2, mais j'ai aussi Rails 3.0.3 installé.
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 Rails 4:
Rails generate migration CreateJoinTableStudentTeacher student teacher
pour Rails 3:
Rails generate migration students_teachers student_id:integer teacher_id:integer
pour Rails <
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)
et ensuite pour 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|
UNE has_and_belongs_to_many
table doit correspondre à ce format. Je suppose que les deux modèles seront rejoints par has_and_belongs_to_many
sont déjà dans le DB: 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, alors vous devriez (dans Rails3) passer :uniq => true
à has_and_belongs_to_many
.
Plus d'informations: Rails Docs
MIS À JOUR LE 12/12/2010 Je l'ai mis à jour pour supprimer l'id et l'horodatage ... En gros MattDiPasquale
et nunopolonia
sont corrects: il ne doit pas y avoir d’identifiant, ni d’horodatage ni Rails ne permet pas has_and_belongs_to_many
travailler.
Vous devez nommer la table les noms des 2 modèles que vous souhaitez connecter par ordre alphabétique et placer les deux identifiants de modèle dans la table. 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: à travers
La réponse en haut montre un indice composite qui, à mon avis, ne sera pas utilisé pour rechercher des pommes dans des 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 à cela basée sur "Le Docteur Qu'est-ce que" est utile et la discussion l'est certainement aussi.
Dans 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, je reçois 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 des index sur ces colonnes car je vais souvent faire des recherches à l'aide de ces colonnes.