La création d'une relation plusieurs-à-plusieurs dans les Rails
C'est un exemple simplifié de ce que je suis en train de réaliser, je suis relativement nouveau sur les Rails et je suis mal à obtenir ma tête autour des relations entre les modèles.
J'ai deux modèles, la User
modèle et la Category
modèle. Un utilisateur peut être associé à de nombreuses catégories. Une catégorie particulière peut apparaître dans la liste des catégories pour de nombreux utilisateurs. Si une catégorie est supprimée, cela devrait être reflété dans la liste des catégories pour un utilisateur.
Dans cet exemple:
Mon Categories
table contient cinq catégories:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ID | Nom | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 1 | Sport | | 2 | Nouvelles | | 3 | Divertissement | | 4 | Technologie | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mon Users
table contient deux utilisateurs:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ID | Nom | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 1 | UserA | | 2 | UserB | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
L'utilisateur peut choisir de Sport et de la Technologie dans ses catégories
L'utilisateur b peut choisir de Nouvelles, de Sports et de Divertissement
La catégorie sports est supprimé, à la fois l'Utilisateur a et utilisateur b catégorie des listes de tenir compte de la suppression
J'ai joué avec la création d'un UserCategories
table qui contient l'id d'une catégorie et de l'utilisateur. Ce genre de travaillé, j'ai pu regarder jusqu'à la catégorie des noms, mais je ne pouvais pas obtenir une suppression en cascade de travail et l'ensemble de la solution semblait mal.
Les exemples d'utilisation de l'belongs_to et has_many fonctions que j'ai trouvé semble pour discuter de la cartographie d'un one-to-one relation. Par exemple, des commentaires sur un blog.
- Comment représentez-vous ce plusieurs-à-plusieurs relations en utilisant le haut-dans les Rails de la fonctionnalité?
- Est à l'aide d'un tableau distinct entre les deux une solution viable lors de l'utilisation de Rails?
- En fait, il n'y a rien de mal à utiliser le
UserCategory
modèle, il est même souhaitable dans la plupart des cas. Vous avez juste besoin d'utiliserUser.has_many :categories, through: :user_categories
. Peut-être, un meilleur nom pourrait être trouvées. - Pour les autres, il y a un bon rails en fonte, ici, sur le sujet: railscasts.com/episodes/47-two-many-to-many
Vous devez vous connecter pour publier un commentaire.
Vous voulez un
has_and_belongs_to_many
relation. Le guide fait un excellent travail en décrivant comment cela fonctionne avec les cartes et tout et tout:http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
Vous allez vous retrouver avec quelque chose comme ceci:
Vous devez maintenant créer une table de jointure pour les Rails à utiliser. Rails de ne pas faire cela automatiquement pour vous. C'est effectivement un tableau avec une référence à chacune des Catégories et les Utilisateurs, et pas de clé primaire.
Générer une migration à partir de la CLI comme ceci:
Puis l'ouvrir et le modifier pour correspondre à:
Pour les Rails 4.0.2+ (y compris les Rails 5.2):
Rails < 4.0.2:
Avec que en place, d'exécuter les migrations et vous pouvez vous connecter Catégories et les Utilisateurs avec l'ensemble de la pratique des accesseurs vous en avez l'habitude:
User.categories
etc. Les idées de ce que je pourrais être absent?User
, et non pas la classe.:id => false do |t|
)Le plus populaire est " Mono-transitive de l'Association, vous pouvez faire ceci:
Juste en complément coreyward la réponse ci-dessus:
Si vous avez déjà un modèle qui dispose d'un
belongs_to
,has_many
relation et vous souhaitez créer une nouvelle relationhas_and_belongs_to_many
en utilisant la même table, vous aurez besoin de:Puis,
Après, vous devez définir vos relations:
De l'utilisateur.rb:
Catégorie.rb
Afin de remplir la nouvelle table de jointure avec les anciennes données, vous devrez dans votre console:
Vous pouvez soit laisser le
user_id
colonne etcategory_id
colonne à partir de la Catégorie et les tables de l'Utilisateur ou de créer une migration de le supprimer.