Domanda

Ho una struttura n ... n per due tabelle, ma e modelli . Finora nessun problema.

In una terza tabella ( prodotti ) come:

id
make_id
model_id
...

Il mio problema è la creazione di una vista per prodotti di una specifica ma all'interno del mio ProductsController contenente solo i modelli di marca:

Ho pensato che potesse funzionare:

var $uses = array('Make', 'Model');

$this->Make->id = 5; // My Make

$this->Make->find(); // Returns only the make I want with it's Models (HABTM)
$this->Model->find('list'); // Returns ALL models
$this->Make->Model->find('list'); // Returns ALL models

Quindi, se voglio usare list per passare alla mia vista per creare pulsanti di opzione, dovrò fare un foreach () nel mio < code> make array per trovare tutti i titoli dei modelli e creare un nuovo array e inviarlo alla vista tramite $ this- > set () .

$makeArray = $this->Make->find();
foreach ($makeArray['Model'] as $model) {
    $modelList[] = $model['title'];
}
$this->set('models', $models)

Esiste un modo più semplice per ottenere tale elenco senza stressare l'array make . Sarà un compito comune sviluppare tali scenari nelle mie applicazioni.

Grazie in anticipo per qualsiasi suggerimento!

È stato utile?

Soluzione 5

La soluzione può essere raggiunta con l'uso dell'operazione with nella matrice habtm sul modello.

Usando con puoi definire " middle " tabella come:

$habtm = " ...
  'with' => 'MakeModel',
   ... ";

E internamente, nel Modello o nel Controller, è possibile emettere condizioni per il metodo find .

Vedi: http: / /www.cricava.com/blogs/index.php?blog=6&title=modelizing_habtm_join_tables_in_cakephp_&more=1&c=1&tb=1&pb=1

Altri suggerimenti

Ecco il mio suggerimento: prova a scrivere la tua query in SQL normale prima di provare a ricostruire usando la libreria Cake. In sostanza stai facendo un sacco di lavoro extra che il DB può fare per te. Il tuo approccio (solo per show - SQL non buono):

SELECT * FROM makes, models, products WHERE make_id = 5

Non stai prendendo in considerazione le relazioni (a meno che Cake non capisca automaticamente le relazioni delle tabelle)

Probabilmente stai cercando qualcosa che unisca queste cose:

SELECT models.title FROM models 
INNER JOIN products 
  ON products.model_id = models.model_id 
  AND products.make_id = 5

Speriamo che questa sia una spinta nella giusta direzione?

A giudicare dal tuo commento, ciò che stai chiedendo è come ottenere risultati da un determinato modello, in cui la condizione è in un modello correlato a HABTM. Cioè qualcosa che faresti normalmente con un'istruzione JOIN in SQL raw.
Attualmente è uno dei pochi punti deboli di Cake. Esistono diverse strategie per affrontarlo.

  • Chiedi al modello B correlato di restituire tutti gli ID dei possibili candidati per il modello A, quindi esegui una seconda query sul modello A. I.e .:

    $this->ModelB->find('first', array('conditions' => array('field' => $condition)));
    array(
        ['ModelB'] => array( ... ),
        ['ModelA'] => array(
            [0] => array(
                'id' => 1
            )
    )
    

    Ora hai un array di tutti gli ID di ModelA che appartengono a ModelB che corrispondono alle tue condizioni, che puoi estrarre facilmente usando Set :: extract (). Fondamentalmente l'equivalente di SELECT model_a.id FROM model_b JOIN model_a DOVE model_b.field = xxx . Quindi cerchi ModelA:

     $this->ModelA->find('all', array('conditions' => array('id' => $model_a_ids)));
    

    Questo produrrà SELEZIONA model_a. * FROM model_a WHERE id IN (1, 2, 3) , che è un modo rotonda di fare l'istruzione JOIN. Se sono necessarie condizioni su più di un modello correlato, ripetere fino a quando non si hanno tutti gli ID per ModelA, SQL utilizzerà l'intersezione di tutti gli ID ( WHERE id IN (1, 2, 3) E id IN (3, 4 , 5) ).

  • Se hai bisogno di una sola condizione su ModelB ma vuoi recuperare ModelA, cerca ModelB. Cake recupererà automaticamente i ModelAs correlati per te (vedi sopra). Potrebbe essere necessario Set :: extract () di nuovo, ma potrebbe essere già sufficiente.

  • Puoi usare il metodo sopra e combinarlo con il Comportamento contenitore per avere un maggiore controllo sui risultati.

  • Se tutto il resto fallisce o i metodi sopra descritti producono semplicemente un sovraccarico eccessivo, puoi comunque scrivere il tuo SQL grezzo con $ this- > Model- > query () . Se ti attieni agli standard Cake SQL (denominando correttamente le tabelle con FROM model_as AS ModelA ) Cake continuerà comunque a elaborare correttamente i risultati.

Spero che questo ti mandi nella giusta direzione.

Tutte le tue diverse chiamate Make- > find () e Model- > find () sono completamente indipendenti l'una dall'altra. Anche Make- > Model- > find () è lo stesso di Model- > find (), Cake non ricorda in alcun modo o tiene conto di ciò che hai già trovato in altri modelli. Quello che stai cercando è qualcosa di simile:

$this->Product->find('all', array('conditions' => array('make_id' => 5)));

Dai un'occhiata al metodo Set :: extract () per ottenere un elenco di titoli dei modelli dai risultati di $ this- > Make- > find ()

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