2010-06-16 4 views
12

Dato che devi implementare un feed di notizie come quello visto nei social network, ex facebook. Attualmente sto usando una classe News che ha un'associazione polimorfica che può essere di qualsiasi tipo come Immagine, Commento, Amicizia, GruppoMembership, ecc. Ogni volta che viene creato un Oggetto, come viene creato anche Notizie. Funziona bene con AR (ActiveRecords), ma mi trovo nei guai quando passerei a DM (DataMapper) o Sequel in quanto entrambi non supportano nativamente le associazioni polimorfiche e scoraggiano il suo utilizzo.come evitare le associazioni polimorfiche

Una soluzione alternativa sarebbe utilizzare una grande clausola SQL con un sacco di UNION per unire tutte le diverse tabelle che dovrebbero essere considerate come notizie. Ma questo ha alcuni inconvenienti, specialmente le prestazioni sarebbero terribili.

Quindi mi chiedo come risolvere senza associazioni polimorfiche ottenendo comunque buone prestazioni e nessun altro inconveniente, come avere la possibilità di aggiungere metadati a una notizia?

risposta

21

Disclaimer: Sono lo sviluppatore principale di Sequel.

Il modo migliore per farlo dipende in genere da quali tipi di cose si desidera fare con i dati. Un modo per andare a questo proposito è quello di avere le colonne chiave esterna per tutte le possibili relazioni:

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

non c'è davvero nessuna differenza di prestazioni nel fare le cose in questo modo contro avere una chiave esterna generico e la memorizzazione di un nome di classe. Per il caricamento lazy, basta selezionare il campo chiave esterna che non è nullo/NULL e scegliere l'associazione appropriata da caricare. Per il caricamento di query-per-table eager, basta caricare tutte le associazioni contemporaneamente. Questo è anche più flessibile in quanto è possibile caricare con entusiasmo utilizzando JOINs, il che non è possibile con l'approccio polimorfico. Inoltre, ottieni il vantaggio della vera integrità referenziale.

Uno svantaggio è che se si desidera aggiungere più tipi di associazione in futuro, è necessario aggiungere chiavi esterne alla tabella.

+0

Grazie ... questa è una vera semplice ma buona idea :-). Richiede alcune modifiche al modello (restituendo la vera associazione del ref) ma dovrebbe essere ok :) – gucki

+0

Non penso davvero che questa sia la soluzione. In realtà non descrive il concetto di ad es. un 'revisionabile' potenzialmente un 'Business' o un' Person' o un 'Item'. Anche se possiedi ognuno di 'business_id',' person_id', 'item_id' in una tabella' Review' devi trovare il primo campo non nullo tra tutti quelli per sapere veramente a cosa punta la recensione. E i casi in cui una particolare associazione può essere una delle tante cose diverse? – fatuhoku

2

Ecco un gioiello per mantenere l'integrità referenziale dei polimorfi Associazioni a livello di database in Rails:

https://github.com/mkraft/fides

Come di questo intervento ci sono adattatori per SQLite3 e PostgreSQL.

Disclaimer: Ho scritto la gemma.