2010-02-13 12 views
6

Nell'applicazione che sto creando, gli utenti possono specificare le relazioni tra le tabelle.Come si aggiungono relazioni in fase di esecuzione utilizzando DBIx :: Class e Catalyst?

Poiché l'ho determinato solo in fase di esecuzione, non è possibile specificare has_many o belongs_to nelle relazioni nei moduli dello schema per l'avvio.

Quindi dato due tabelle; sistema e luogo, vorrei aggiungere la relazione per unire i record tra loro.

devo parte della soluzione qui di seguito:

$rs = $c->model('DB::system')->result_source; 
$rs->add_relationship('locations','DB::place',{'foreign.fk0' => 'self.id'}); 

Così la colonna fk0 sarebbe la mappatura chiave esterna al primario posizione chiave id.

So che ci deve essere una nuova registrazione per consentire l'accesso futuro alla relazione, ma non riesco a capirlo.

+3

Sei sicuro che gli utenti cambino davvero lo schema del database? Questo è esattamente equivalente a consentire loro di modificare il codice sorgente. Non è necessario necessariamente modellare la "propria interfaccia utente" con DBIx :: Class. Probabilmente vorrai sviluppare una rappresentazione intermedia che fornisca la funzionalità che desideri e mantenere il codice e lo schema del database corretti. – jrockway

+1

C'è anche DBIx :: Class :: Schema :: Loader, se si sta monitorando un database che non si controlla, o qualcosa del genere. Ma tieni presente che le modifiche allo schema del database cambieranno il comportamento della tua applicazione. Se il tuo codice è statico e lo schema del tuo database è dinamico, c'è sicuramente qualcosa di sbagliato. – jrockway

+0

Sto esplorando la possibilità di utilizzare il mio schema/dizionario dati sovrapposto al database reale. Ho una tabella 'colonne' e una tabella 'tabelle'. Questi sono usati per mappare i nomi delle tabelle e delle colonne selezionati dall'utente e gli attributi su un tablespace generico sottostante. Pertanto, gli utenti possono scegliere di aggiungere relazioni tra tabelle in fase di esecuzione. Vorrei accedere a questa relazione tramite DBIx. Sto costruendo un'interfaccia intermedia per nascondere lo schema generico e ho bisogno di questa capacità. Grazie, -Joe – Joe

risposta

1

Non credo che sia possibile ridefinire queste relazioni dopo che un'applicazione è già in esecuzione. Almeno non senza scartare oggetti DBIC esistenti e ricrearli tutti da zero. A quel punto, sarebbe più facile riavviare la tua applicazione, sospetto.

Se siete soddisfatti di definire dinamicamente queste cose al compilare il tempo, è possibile ... facciamo qualcosa di simile in una delle nostre applicazioni.

Se ciò ti sarebbe utile, posso fornire un codice di esempio.

Il modulo DBIx::Class::ResultSet::View potrebbe fornire un'approssimazione approssimativa di ciò che si sta cercando, consentendo l'esecuzione di codice arbitrario, ma recuperando i risultati come oggetti DBIx.

La mia opinione generale su cose come questa, è che qualsiasi livello di astrazione (e un ORM è un livello di astrazione), è destinato a semplificare la vita. Quando interferisce con il fare che l'applicazione faccia ciò che vuole, non rende più la vita più facile e deve essere scartata (per quell'uso specifico, non necessariamente per ogni uso). Per questo motivo, suggerirei di utilizzare DBI, come suggerito in uno dei tuoi commenti. Sospetto che in questo caso ti renderà la vita molto più facile.

+0

+1 per il commento "quando si mette in mezzo ...". Uno dei motivi per cui preferisco ancora Class :: DBI over DBIC - non trovo che interferisca. – RET

0

Ho fatto questo chiamando i metodi appropriati sulle fonti dei risultati rilevanti, ad es. $resultset->result_source-><relationship method>. Funziona anche in un'applicazione attiva.

Problemi correlati