# Relazioni polimorfiche many to many

**URL:** <https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602>\
**Category:** IT\
**Created:** [June 16, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602 "2008-06-16T18:45:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gianluca\_t](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d78d45/32.png) [@gianluca\_t](https://www.ruby-forum.com/u/gianluca_t)\
**Post date:** [June 16, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602/1 "2008-06-16T18:45:51Z")

</div>

Ciao a tutti,

mi sto scervellando su un problema non banale.

Ho la necessità di dover collegare ‘n’ modelli tra di loro, es.:

Zone  
Prodotti  
Fornitori  
Categorie  
Alberghi  
Strutture  
ecc.

Il problema è che dovrei fare in modo che ad esempio data una zona possa  
“abbinare” n prodotti, n fornitori, n categorie, n zone (self  
reference), stessa cosa però vale per tutti gli altri modelli, avrei  
anche necessità di recuperare la relazione dall’altro lato (double-side  
relation) es.

se abbino n prodotti ad una zona, a partire dal prodotto voglio vedere  
tutte le zone collegate ecc.

Ora, sono partito pensando ad una tabella di join (habtm) per ogni  
collegamento ma arrivo ad avere un numero di tabelle di join enorme  
anche solo con 7/8 tabelle =\> (n^2+n)/2

Sono quindi passato a provare has\_many\_polymorphs ma non riesco a capire  
come gestire la relazione molti a molti tra tabelle diverse…

Mi spiego meglio, se gestisco un’unica tabella di join polimorfico tra  
padre e figlio generico, se dal padre voglio ottenere i figli tutto bene  
ma come faccio dai figli recuperare i padri non sapendo a priori se  
questi sono stati inseriti come padri o come figli ?

Qualcuno si è già cimentato sulla risoluzione di un problema simile ?  
(mi basterebbe avere una dritta su quale è la tecnica migliore per la  
risoluzione del problema…)

Grazie 1000 !

---

<div class="post-metadata">

**Author:** ![gianluca\_t](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d78d45/32.png) [@gianluca\_t](https://www.ruby-forum.com/u/gianluca_t)\
**Post date:** [June 16, 2008, 7:19pm UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602/2 "2008-06-16T19:19:44Z")

</div>

Ti aiuterei volentieri ma sono fermo ancora alla lettura del primo  
capitolo di Ruby 🙂

---

<div class="post-metadata">

**Author:** ![gianluca\_t](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d78d45/32.png) [@gianluca\_t](https://www.ruby-forum.com/u/gianluca_t)\
**Post date:** [June 17, 2008, 12:11am UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602/3 "2008-06-17T00:11:48Z")

</div>

Ciao, per darti una dritta, potresti avere un ipotetica tabella items  
(nome  
fittizzio) in cui avresti una colonna item\_type e item\_id. Questa  
tabella è  
polimorfica, nel senso che zone avrà molti prodotti e per trovarli andrà a  
vedere i record della tabella che su item\_type hanno ‘prodotto’.  
Dopodichè  
pescherà il record dalla tabella prodotti tramite in base al campo type\_id  
corrispondente

Già così è molto controverso, fare la stessa cosa per tutte le altre tabelle  
(un fornitore può avere diversi prodotti) diventa un impresa quasi  
impossibile con questo design. In rails 2.1 mi sembra sia possibile  
accedere  
alla relazione polimorfica in entrambi i sensi. Il mio consiglio è però  
quello di ripensare alla struttura per renderla più semplice. Altrimenti  
sarebbe solo il primo di una serie di problemi (prova a pensare alla  
performance e  
mantenibilità)  
2008/6/16, Gianluca T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![gianluca\_t](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d78d45/32.png) [@gianluca\_t](https://www.ruby-forum.com/u/gianluca_t)\
**Post date:** [June 17, 2008, 8:54am UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602/4 "2008-06-17T08:54:03Z")

</div>

Il giorno 16/giu/08, alle ore 18:45, Gianluca T. ha scritto:

> Zone  
> Prodotti  
> Fornitori  
> Categorie  
> Alberghi  
> Strutture  
> […]

Ad occhio potresti usare un has\_many\_through e rendere polimorfica la  
relazione su Zone. Se ho più tempo dopo provo a scrivere un esempio 🙂

---

<div class="post-metadata">

**Author:** ![gianluca\_t](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d78d45/32.png) [@gianluca\_t](https://www.ruby-forum.com/u/gianluca_t)\
**Post date:** [June 17, 2008, 4:00pm UTC](https://www.ruby-forum.com/t/relazioni-polimorfiche-many-to-many/140602/5 "2008-06-17T16:00:11Z")

</div>

Grazie a tutti quelli che mi hanno risposto.

Alla fine ci sono riuscito !!!

Utilizzando has\_many\_polymorphs è quindi possibile mettere in relazione  
n tabelle con n tabelle in modalità self-referential e double-side  
relationship.

Per fare questo ho installato il plugin e poi semplicemente mi sono  
creato un model di collegamento many to many polimorfico:

class Link \< ActiveRecord::Base  
belongs\_to :linker, :polymorphic =\> true  
belongs\_to :linkable, :polymorphic =\> true

acts\_as\_double\_polymorphic\_join :linkers =\> [:zones, :hostels,  
:producers, :suppliers, :products],  
:linkables =\> [:zones, :hostels,  
:producers, :suppliers, :products]  
end

Gli altri model non li ho toccati, per la migration ho fatto  
così:  
class CreateLinks \< ActiveRecord::Migration  
def self.up  
create\_table :links do |t|  
t.references :linker, :polymorphic =\> true  
t.references :linkable, :polymorphic =\> true

```
  t.timestamps
end

```

end

def self.down  
drop\_table :links  
end  
end

E poi l’esempio di funzionamento è questo:

Product.create(:name =\> “P1”)  
=\> #\<Product id: 1, name: “P1”, created\_at: “2008-06-17 13:36:31”,  
updated\_at: “2008-06-17 13:36:31”\>

> > Supplier.create(:name =\> “S1”)  
> > =\> #\<Supplier id: 1, name: “S1”, created\_at: “2008-06-17 13:36:47”,  
> > updated\_at: “2008-06-17 13:36:47”\>

Product.first.linkables \<\< Supplier.first  
=\> [#\<Supplier id: 1, name: “S1”, created\_at: “2008-06-17 13:36:47”,  
updated\_at: “2008-06-17 13:36:47”\>]

> > Product.first.suppliers  
> > =\> [#\<Supplier id: 1, name: “S1”, created\_at: “2008-06-17 13:36:47”,  
> > updated\_at: “2008-06-17 13:36:47”\>]

> > Supplier.first.products  
> > =\> [#\<Product id: 1, name: “P1”, created\_at: “2008-06-17 13:36:31”,  
> > updated\_at: “2008-06-17 13:36:31”\>]

> > Product.first.linkables  
> > =\> [#\<Supplier id: 1, name: “S1”, created\_at: “2008-06-17 13:36:47”,  
> > updated\_at: “2008-06-17 13:36:47”\>]

> > Product.first.linkables \<\< Product.find(2)  
> > =\> [#\<Supplier id: 1, name: “S1”, created\_at: “2008-06-17 13:36:47”,  
> > updated\_at: “2008-06-17 13:36:47”\>, #\<Product id: 2, name: “P2”,  
> > created\_at: “2008-06-17 13:36:33”, updated\_at: “2008-06-17 13:36:33”\>]

> > Product.first.products  
> > =\> [#\<Product id: 2, name: “P2”, created\_at: “2008-06-17 13:36:33”,  
> > updated\_at: “2008-06-17 13:36:33”\>]

Direi FANTASTICO !!!

POSSO QUINDI ASSOCIARE QUALUNQUE COSA IO VOGLIA MEDIANTE UN’UNICA  
TABELLA !!!

L’unico dubbio che mi rimane è che devo per forza associare tramite  
.linkables al posto di utilizzare ad esempio .products perchè le  
collezioni sono sempre frozen ma credo che questo sia “by design…”.
