2010-06-16 3 views
12

Étant donné que vous devez mettre en œuvre un fil de nouvelles comme celui vu dans les réseaux sociaux, ex facebook. Actuellement j'utilise une classe News qui a une association polymorphe qui peut être de n'importe quelle sorte comme Image, Comment, Amitié, GroupMembership, etc. Chaque fois qu'un objet est créé, comme News est créé aussi. Cela fonctionne bien avec AR (ActiveRecords) mais j'ai des ennuis quand je passerais à DM (DataMapper) ou à Sequel car les deux ne supportent pas nativement les associations polymorphes et découragent son utilisation.comment éviter les associations polymorphes

Une solution de contournement serait d'utiliser une grande clause SQL avec beaucoup d'UNION pour fusionner toutes les différentes tables qui devraient être considérées comme des nouvelles. Mais cela a quelques inconvénients, escpecially performance serait terrible. Donc je me demande comment résoudre sans associations polymorphes tout en obtenant de bonnes performances et aucun autre inconvénient, comme avoir la possibilité d'ajouter des méta-données à une nouvelle?

Répondre

21

Avertissement: Je suis le développeur principal de Sequel.

La meilleure façon de procéder dépend généralement des types de choses que vous voulez faire avec les données. Une façon de s'y prendre est d'avoir des colonnes clés étrangères pour toutes les relations possibles:

news: 
    id 
    ... (Other columns) 
    image_id 
    comment_id 
    friendship_id 
    group_membership_id 

Il n'y a vraiment pas de différence de performance à faire des choses de cette façon plutôt que d'avoir une clé étrangère générique et le stockage d'un nom de classe. Pour un chargement paresseux, il vous suffit de sélectionner le champ de clé étrangère qui n'est pas nul/NULL et de choisir l'association appropriée à charger. Pour le chargement avide de requête par table, il vous suffit de charger toutes les associations à la fois. Ceci est également plus flexible dans la mesure où vous pouvez charger avec empressement des JOINs, ce qui n'est pas possible avec l'approche polymorphe. De plus, vous bénéficiez de l'intégrité référentielle réelle. Le seul inconvénient est que si vous voulez ajouter plus de types d'association à l'avenir, vous devez ajouter des clés étrangères à la table.

+0

Merci ... c'est une idée simple mais bonne :-). Cela demande quelques changements au modèle (renvoyant l'association réelle de l'arbitre) mais cela devrait être correct :) – gucki

+0

Je ne pense pas vraiment que ce soit la solution. Il ne décrit pas vraiment le concept de par ex. un «révisable» pouvant être une «entreprise» ou une «personne» ou un «article». Même si vous avez chacun «business_id», «person_id», «item_id» dans une table «Review», vous devez trouver le premier champ non-nul de tous les champs pour vraiment savoir à quoi pointe la critique. Qu'en est-il des cas où une association particulière peut être l'une des nombreuses choses différentes? – fatuhoku

2

est ici un petit bijou pour maintenir l'intégrité référentielle des associations polymorphes au niveau de base de données Rails:

https://github.com/mkraft/fides

À partir de cette publication, il y a des adaptateurs pour SQLite3 et Postgresql.

Clause de non-responsabilité: J'ai écrit la gemme.

Questions connexes