2009-03-18 5 views
22

Y at-il quelque chose qui ne va pas avec l'utilisation de has_and_belongs_to_many associations dans les rails au lieu de has_many: through? Je suis au courant de thesearticlesdescribing différences et de contourner, mais ils sont de 2006. De choses que j'ai lu sur SO, il semble que les gens pensent que habtm est vieux et maladroit, mais que se passe-t-il si un simple à plusieurs rejoindre aucun modèle nécessaire n'est ce que vous cherchez?has_and_belongs_to_many in Rails

Pensées?

Répondre

29

has_and_belongs_to_many est destiné aux relations simples-multiples. D'autre part, through_many est destiné à des relations un-à-plusieurs indirectes, ou à des relations plusieurs-à-plusieurs avec des propriétés.

Si vous recherchez uniquement une relation simple-à-plusieurs, je ne vois aucune raison de ne pas utiliser has_and_belongs_to_many.

Exemple many-to-many:

utilisateur appartient à zéro ou plusieurs groupes, et le groupe a zéro ou plusieurs membres (utilisateurs).

Exemple plusieurs à plusieurs avec des propriétés:

utilisateur appartient à zéro ou plusieurs groupes, et le groupe a zéro ou plusieurs membres avec rangs. Par exemple, Alice peut être un administrateur du groupe A et un modérateur du groupe B. Vous pouvez détenir cette propriété dans la table de jointure.

Exemple indirect one-to-many relation:

Une catégorie a zéro ou plusieurs sous-catégories, et chaque sous-catégorie a zéro ou plusieurs éléments.

Une catégorie a donc zéro élément ou plus à travers ses sous-catégories.

Tenir compte de ces catégories:

alimentaires → Fruits, légumes
Fruits → Apple, Orange, etc.
Légumes → carotte, céleri, etc.

donc:

Alimentation → Pomme, orange, carotte, céleri, etc.

+2

Pour comprendre la récursivité, vous devez d'abord comprendre la récursivité. Je pense que votre réponse pourrait être plus claire ou démonstrative en ce qui concerne les relations plusieurs-à-plusieurs avec les propriétés plutôt que les relations plusieurs-à-plusieurs sans propriétés. –

+3

Laissez-moi ajouter quelques exemples. –

+0

+1, ça m'a beaucoup aidé aussi. –

3

Il n'y a rien de mal à utiliser has_and_belongs_to_many si vous n'avez pas besoin d'un modèle de jointure. Je viens de l'utiliser moi-même sur un projet récent.

+0

comment pouvez-vous utiliser cela avec 'accept_nested_attribute_for'? merci – hqt

3

Je n'utiliserais jamais HABTM non pas pour des soucis d'élégance, mais parce que je peux toujours imaginer vouloir ajouter des données à une relation dans le futur même si je ne peux pas voir le point maintenant. Étant paresseux, j'aimerais pouvoir ajouter les colonnes à la jointure plutôt que d'avoir à retravailler les relations, puis à ajouter les colonnes.

+7

Jamais? Vraiment? Comme jamais comme dans "Je n'utilise jamais goto"? –

+0

Je suppose que si je pouvais trouver une relation où il serait logiquement impossible d'ajouter des données, je pourrais choisir d'aller avec HABTM. Sinon, j'irais avec has_many: à travers. – srboisvert

3

Je pense à ce sujet de cette façon. En supposant que vous avez déjà constaté que vous avez besoin d'un grand nombre à plusieurs modèles:

X----1 
    __/ 
/
Y----2 
    __/ 
/ 
Z----3 

(X-> 1 y-> 1,2 Z-> 2,3)

Utilisez une relation HABTM Si vous n'avez pas besoin de stocker des informations sur chacune des lignes de mon image (je l'espère reconnaissable) ci-dessus.

Si vous avez besoin de stocker des informations sur ces lignes (relations), utilisez un "par". Donc, si vous dites simplement que les gens [XYZ] ont et appartiennent à des projets [123] mais n'ont pas besoin de dire quoi que ce soit à propos de la personne X sur le projet 1, utilisez un HABTM.

Si vous voulez dire que cette personne X a le projet 1 et a été affecté à ce projet à une date donnée, vous avez soudainement un bon pour cette relation particulière et mieux utiliser HMT.

+3

+1 pour le diagramme doux – jbnunn

+1

Hoho, merci! Graphiques ASCII pour la victoire! – Jon