CakePHP i risultati delle query ordine su più di 1 livello
-
21-09-2019 - |
Domanda
Sto usando il comportamento contenibile per ottenere un elenco di commenti (belongsTo Post, che appartiene alla domanda; domanda hasMany postali, e Post hasMany commenti; tutti questi appartengono agli utenti).
$data = $this->Question->find ( 'first',
array ('contain' =>
array ('User',
'Post' => array ('User', /* 'order' => 'User.created DESC'*/ )
)
)
);
Funziona, quando io commento la sezione commenti di cui sopra. Suppongo che questo è da aspettarselo, ma quello che voglio è tutti i messaggi che si trovano, devono essere ordinati in ordine di campo 'creato' del 'utente' a cui appartengono. Come posso realizzare questo livello più profondo l'ordinamento in CakePHP? Ho sempre trovato, "Avvertimento (512): SQL Errore: 1054: Unknown colonna 'creato dall'utente' in 'clausola di ordine'"
Grazie per il vostro aiuto!
Soluzione
Inoltre, si potrebbe tentare di gruppo su una tabella correlata da una chiamata find che non utilizza join.
Impostare il livello di debug a qualcosa di più grande di 1 in modo da poter vedere il log delle query e assicurarsi che torta non sta facendo due query per recuperare i dati. Se questo è il caso, allora la prima query non viene effettivamente riferimento a seconda tabella.
Se si vuole forzare manualmente un join in queste situazioni è possibile utilizzare l'Ad-Hoc unisce metodo indicato da Nate al seguente link.
http: / /bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find
Altri suggerimenti
Ho trovato due modi per aggirare questo. Il primo è quello di definire il secondo livello Associacion direttamente nel modello. Ora si avrà accesso a questi dati in tutto il mondo. Dovrebbe essere qualcosa di simile .....
var $belongsTo = array(
'Foo' => array(
'className' => 'Foo', //unique name of 1st level join ( Model Name )
'foreignKey' => 'foo_id', //key to use for join
'conditions' => '',
'fields' => '',
'order' => ''
),
'Bar' => array(
'className' => 'Bar', //name of 2nd level join ( Model Name )
'foreignKey' => false,
'conditions' => array(
'Bar.id = Foo.bar_id' //id of 2nd lvl table = associated column in 1st level join
),
'fields' => '',
'order' => ''
)
);
Il problema di questo metodo è che si potrebbe fare domande di carattere generale più complessa di quanto non devono necessariamente essere. È possibile quindi anche aggiungere la seconda query di livello direttamente in te trovare o impaginare economico come segue: (Nota: ho trovato che per qualche motivo non è possibile utilizzare le associazioni $ belongsTo nel secondo livello unisce e sarà necessario ridefinire loro se sono già definiti. ad esempio, se 'Foo' è già definito in $ belongsTo, è necessario creare un duplicato 'foo1' per rendere il lavoro dell'associazione, come nell'esempio qui sotto).
$options['joins'] = array(
array('table' => 'foos',
'alias' => 'Foo1',
'type' => 'inner',
'conditions' => array(
'CurrentModel.foo_id = Foo1.id'
)
),
array('table' => 'bars',
'alias' => 'Bar',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array(
'Bar.id = Foo1.bar_id'
)
)
);
$options['conditions'] = array('Bar.column' => "value");
$this->paginate = $options;
$[modelname] = $this->paginate();
$this->set(compact('[modelname]'));
Spero che questo sia abbastanza chiaro da capire e che aiuta qualcuno.
Controlla il tuo valore ricorsiva. Se è troppo limitante, ignorerà i link contenibili, IIRC. Mi ricordo di sbattere contro un paio di volte. Mi piacerebbe provare che contiene più modelli, ma la mia opzione recursive
è stato fissato a 0
e nulla sarebbe ottenere tirato. Per il vostro esempio, mi piacerebbe pensare che un valore di 1
(impostazione predefinita) sarebbe sufficiente, ma forse hai esplicitamente impostato a 0
da qualche parte?
È possibile aggiungere prima della chiamata a trovare () il seguente:
$this->Question->order = 'Question.created DESC';
Si, io non riuscivo a capire come ordinare sulla base del relativo modello / associati, così finito per usare il metodo Set::sort()
. Acquista questo articolo per una buona spiegazione.
// This finds all FAQ articles sorted by:
// Category.sortorder, then Category.id, then Faq.displaying_order
$faqs = $this->Faq->find('all', array('order' => 'displaying_order'));
$faqs = Set::sort($faqs, '{n}.Category.id', 'ASC');
$faqs = Set::sort($faqs, '{n}.Category.sortorder', 'ASC');
... E sì, probabilmente dovrebbe essere un Category->find()
ma purtroppo lo sviluppatore originale non ha il codice in questo modo, e non ho voglia di rielaborare i punti di vista.