Unire automaticamente le tabelle senza interrompere il comportamento predefinito in Zend Framework

StackOverflow https://stackoverflow.com/questions/234785

  •  04-07-2019
  •  | 
  •  

Domanda

La situazione è la seguente: ho 2 modelli: "Azione" e "Utente". Questi modelli si riferiscono rispettivamente alle tabelle "azioni" e "utenti".

La mia tabella delle azioni contiene una colonna user_id . In questo momento, ho bisogno di una panoramica di tutte le azioni e degli utenti a cui sono assegnati. Quando utilizzo $ action- > fetchAll () , ho solo l'ID utente, quindi voglio poter unire i dati dal modello utente, preferibilmente senza effettuare una chiamata a findDependentRowset () .

Ho pensato di creare metodi personalizzati fetchAll () , fetchRow () e find () nel mio modello, ma questo non avrebbe funzionato comportamento.

Qual è il modo migliore per risolvere questo problema? Qualsiasi aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione

Ho progettato e implementato la funzione di relazioni tra tabelle in Zend Framework.

Il mio primo commento è che non useresti comunque findDependentRowset () - useresti findParentRow () se l'Azione ha un riferimento di chiave esterna all'utente .

$actionTable = new Action();
$actionRowset = $actionTable->fetchAll();
foreach ($actionRowset as $actionRow) {
  $userRow = $actionRow->findParentRow('User');
}

Modifica: nel ciclo ora hai un oggetto $ actionRow e $ userRow. È possibile riscrivere le modifiche al database tramite uno degli oggetti modificando i campi dell'oggetto e chiamando save () sull'oggetto.

Puoi anche usare la classe Zend_Db_Table_Select (che è stata implementata dopo che ho lasciato il progetto) per recuperare un Rowset basato su un join tra Action e User.

$actionTable = new Action();
$actionQuery = $actionTable->select()
  ->setIntegrityCheck(false) // allows joins
  ->from($actionTable)
  ->join('user', 'user.id = action.user_id');
$joinedRowset = $actionTable->fetchAll($actionQuery);
foreach ($joinedRowset as $joinedRow) {
  print_r($joinedRow->toArray());
}

Si noti che tale Rowset basato su una query di join è di sola lettura. Non è possibile impostare i valori dei campi negli oggetti Row e chiamare save () per riportare le modifiche nel database.

Modifica: non è possibile rendere scrivibile un set di risultati uniti arbitrari. Prendi in considerazione un semplice esempio basato sul set di risultati unito sopra:

action_id  action_type  user_id  user_name
   1          Buy          1       Bill
   2          Sell         1       Bill
   3          Buy          2       Aron
   4          Sell         2       Aron

Successivamente per la riga con action_id = 1, cambio uno dei campi che provengono dall'oggetto Utente:

$joinedRow->user_name = 'William';
$joinedRow->save();

Domande: quando visualizzo la riga successiva con action_id = 2, dovrei vedere 'Bill' o 'William'? Se "William", ciò significa che il salvataggio della riga 1 deve aggiornare automaticamente "Bill" a "William" in tutte le altre righe in questo set di risultati? Oppure significa che save () riesegue automaticamente la query SQL per ottenere un set di risultati aggiornato dal database? Cosa succede se la query richiede tempo?

Considera anche il design orientato agli oggetti. Ogni riga è un oggetto separato. È appropriato che chiamare save () su un oggetto abbia l'effetto collaterale di cambiare i valori in un oggetto separato (anche se fanno parte della stessa raccolta di oggetti)? Sembra una forma di Content Coupling per me.

L'esempio sopra è una query relativamente semplice, ma sono consentite anche query molto più complesse. Zend_Db non può analizzare le query con l'intenzione di dire risultati scrivibili da risultati di sola lettura. Questo è anche il motivo per cui le visualizzazioni MySQL non sono aggiornabili.

Altri suggerimenti

Puoi sempre creare una vista nel tuo database che faccia il join per te.

CREATE OR REPLACE VIEW VwAction AS
SELECT [columns]
  FROM action
  LEFT JOIN user
    ON user.id = action.user_id

Quindi usa

$vwAction->fetchAll();

Ricorda solo che le visualizzazioni in MySQL sono di sola lettura (supponendo che si tratti di MySQL)

la creazione di una tabella sql vista non è una buona soluzione per creare un giunto? e dopo una semplice lezione da tavolo per accedervi

Penso che sia meglio se la tua logica è in sql che in php

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top