J'ai deux modèles restaurant
et user
que je souhaite effectuer une relation has_and_belongs_to_many.
Je suis déjà entré dans les fichiers de modèle et ajouté le has_and_belongs_to_many :restaurants
et has_and_belongs_to_many :users
Je suppose qu'à ce stade je devrais pouvoir faire quelque chose comme avec Rails 3:
Rails generate migration ....
mais tout ce que j'ai essayé semble échouer. Je suis sûr que c'est quelque chose de très simple, je suis nouveau sur Rails, donc j'apprends encore.
Vous devez ajouter une table de jointure séparée avec uniquement un restaurant_id
et user_id
(pas de clé primaire), dans ordre alphabétique .
Commencez par exécuter vos migrations, puis modifiez le fichier de migration généré.
Rails 3
Rails g migration create_restaurants_users_table
Rails 4 :
Rails g migration create_restaurants_users
Rails 5
Rails g migration CreateJoinTableRestaurantUser restaurants users
De la docs :
Il existe également un générateur qui produira des tables de jointure si JoinTable fait partie du nom:
Votre fichier de migration (notez le :id => false
; c'est ce qui empêche la création d'une clé primaire):
Rails 3
class CreateRestaurantsUsers < ActiveRecord::Migration
def self.up
create_table :restaurants_users, :id => false do |t|
t.references :restaurant
t.references :user
end
add_index :restaurants_users, [:restaurant_id, :user_id]
add_index :restaurants_users, :user_id
end
def self.down
drop_table :restaurants_users
end
end
Rails 4
class CreateRestaurantsUsers < ActiveRecord::Migration
def change
create_table :restaurants_users, id: false do |t|
t.belongs_to :restaurant
t.belongs_to :user
end
end
end
t.belongs_to
créera automatiquement les index nécessaires. def change
détectera automatiquement une migration en avant ou en arrière, pas besoin de monter/descendre.
Rails 5
create_join_table :restaurants, :users do |t|
t.index [:restaurant_id, :user_id]
end
Remarque: Il existe également une option pour un nom de table personnalisé pouvant être transmise en tant que paramètre à create_join_table appelée table_name
. De la docs
Par défaut, le nom de la table de jointure provient de l'union des deux premiers arguments fournis à create_join_table, dans l'ordre alphabétique. Pour personnaliser le nom de la table, spécifiez une option: nom_table:
Les réponses ici sont assez datées. A partir de Rails 4.0.2, vos migrations utilisent create_join_table
.
Pour créer la migration, exécutez:
Rails g migration CreateJoinTableRestaurantsUsers restaurant user
Cela générera les éléments suivants:
class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
def change
create_join_table :restaurants, :users do |t|
# t.index [:restaurant_id, :user_id]
# t.index [:user_id, :restaurant_id]
end
end
end
Si vous souhaitez indexer ces colonnes, décommentez les lignes respectives et vous êtes prêt à partir!
Lors de la création de la table de jointure, veillez à ce que les deux tables soient répertoriées dans l'ordre ordre alphabétique dans le nom/la classe de la migration. Cela peut facilement vous mordre si vos noms de modèle sont similaires, par exemple. "abc" et "abb". Si tu devais courir
Rails g migration create_abc_abb_table
Vos relations vont pas fonctionner comme prévu. Tu dois utiliser
Rails g migration create_abb_abc_table
au lieu.
Pour les relations HABTM, vous devez créer une table de jointure. Il n'y a qu'une table de jointure et cette table ne doit pas avoir de colonne id. Essayez cette migration.
def self.up
create_table :restaurants_users, :id => false do |t|
t.integer :restaurant_id
t.integer :user_id
end
end
def self.down
drop_table :restaurants_users
end
Vous devez vérifier cette relation Rails)