2009-02-23 12 views
7

Abbiamo una tabella di collegamenti che può gestire più tipi di oggetti su un lato, e non riesco a capire come ottenere da uno di questi oggetti alla tabella dei collegamenti usando has_many.Come si crea una relazione DBIx :: Class con una condizione di join fisso?

Esempio: tabella di collegamento contiene:

id link_id link_table resource_id 
1 1  page  3 
2 1  page  5 
3 2  page  3 
4 1  not_page 1 

Costruire il rapporto dal lato delle risorse è abbastanza facile:

Resource->has_many(links => 'Link', 'resource_id'); 

ma non sono stato in grado di ottenere il corrispondente rapporto dal lato della pagina:

Page->has_many(links => 'Link', 'link_id'); 

otterrebbe il link not_page

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => 'page'}); 

dà un errore 'di pagina non valida val rel cond' (che non era sorprendente per me).

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => '"page"'}); 

restituisce un errore "Pagina di riferimento non valida". Lancio di barre rovesciate non ha aiutato.

DBIx::Class::Relationship::Base dice:

La condizione deve essere una rappresentazione in stile SQL::Abstract del join tra le tabelle

e ho provato diverse opzioni diverse da lì, come ad esempio:

ma senza alcun successo.

Se ho aggiunto un altro campo alla tabella delle pagine che contiene sempre il valore 'pagina' ho potuto fare

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => 'self.what_table_am_i'}); 

ma non è certo una soluzione ottimale.

La suddivisione della tabella di collegamento in una distinta per ogni tipo può essere una possibilità, ma questo è un progetto esistente che viene considerato per l'adattamento a DBIx :: Class e potrebbero esserci altri luoghi in cui suddividere una tabella in più altri tavoli sono più fastidi di quanto valga.

+0

Vuoi "belongs_to" al di là di "has_many"? – jrockway

+0

L'has_many era più importante, quindi ho scelto di non aggiungere più complicazioni alla domanda del necessario. Spero che la risposta di Brian sia in grado di essere modificata per il caso appartiene a caso. – Cebjyre

risposta

3

Si dovrebbe solo fare un metodo wrapper che richiama il rapporto con gli argomenti richiesti:

Page->has_many(__all_links => 'Link', 'link_id'); 

sub links { 
    shift->__all_links({link_table => 'page'}); 
} 

Questo sarebbe abbastanza facile da trasformare in un componente DBIx :: Classe se si dispone di più tabelle che devono avere questo tipo di logica di join.

+0

Brillante, grazie. Avere un biscotto – Cebjyre

+0

E come può essere usato con search()? Ho provato: $ c-> model ('Page') -> search (undef, {prefetch => "links"}) -> all; Ma dice: DBIx :: Class :: ResultSet :: all(): Nessun collegamento di questo tipo nella pagina –

1

Può essere specificato nella chiamata has_many in questo modo:

Page->has_many(links => 'Link', 'link_id', 
        { where => { link_table => 'page'} }); 

See: DBIx::Class Cookbook

Problemi correlati