Ein bisschen Kontext dafür. Ich möchte die Exportfunktion für Kundenaufträge (über das Raster) um weitere Spalten erweitern. Ich habe ein Modul erstellt, das ein neues Raster für den Export und ein neues Sammlungsmodell hinzufügt, das das Original erweitert. Dabei wird die Funktion _beforeLoad () verwendet, damit ich die benötigten Tabellen verknüpfen kann.
Das Problem besteht darin, dass beim Hinzufügen der Filter aus dem Raster (increment_id, Bestelldatum usw.) die hinzugefügte where-Klausel der Tabelle kein Präfix hinzufügt und Probleme mit mehrdeutigen Spaltennamen auftreten. Auf increment_id habe ich beispielsweise das Problem in der where-Klausel:
SELECT `main_table`.*, `sales`.`total_qty_ordered`, `sales`.`entity_id` AS `order_id`, `sagepay`.`vendor_tx_code` FROM `sales_flat_order_grid` AS `main_table`
LEFT JOIN `sales_flat_order` AS `sales` ON main_table.increment_id = sales.increment_id
LEFT JOIN `sagepaysuite_transaction` AS `sagepay` ON order_id = sagepay.order_id WHERE (increment_id LIKE '%100000261%') GROUP BY `main_table`.`entity_id`
Diese where-Klausel wird hinzugefügt, bevor ich die Verknüpfungen mit den anderen Tabellen in der Funktion _addColumnFilterToCollection () durchführe
protected function _addColumnFilterToCollection($column)
{
if ($this->getCollection()) {
$field = ( $column->getFilterIndex() ) ? $column->getFilterIndex() : $column->getIndex();
if ($column->getFilterConditionCallback()) {
call_user_func($column->getFilterConditionCallback(), $this->getCollection(), $column);
} else {
$cond = $column->getFilter()->getCondition();
if ($field && isset($cond)) {
// Filter added at this point
$this->getCollection()->addFieldToFilter($field , $cond);
}
}
}
return $this;
}
Als kurzen Test habe ich die Leitung auf geändert
$this->getCollection()->addFieldToFilter('main_table.' . $field , $cond);
und das hat funktioniert, aber es fühlt sich nicht gut an, es zu tun.
Mein Code in _beforeLoad () ist
protected function _beforeLoad()
{
// Join the sales_flat_order table to get order_id and and total_qty_ordered
$this->getSelect()->joinLeft(array('sales' => $this->getTable('sales/order')),
'main_table.increment_id = sales.increment_id',
array('total_qty_ordered' => 'sales.total_qty_ordered',
'order_id' => 'sales.entity_id'));
// Join the SagePay transaction table to get vendor_tx_code
$this->getSelect()->joinLeft(array('sagepay' => $this->getTable('sagepaysuite2/sagepaysuite_transaction')),
'order_id = sagepay.order_id',
array('vendor_tx_code' => 'vendor_tx_code'));
$this->getSelect()->group('main_table.entity_id');
parent::_beforeLoad();
}
Ich muss increment_id verwenden, um die Kundenauftragsgittertabelle und die SagePay-Transaktionstabelle zu verknüpfen, da dies die einzige häufig verwendete ID ist, die ich sehen kann.
Grundsätzlich frage ich mich, wie ich das am besten angehen kann. Ich könnte wahrscheinlich mit der oben erwähnten Änderung durchkommen, aber es fühlt sich nicht richtig an. Kann ich an meinen Join-Anweisungen etwas ändern?
Vielen Dank.
Antworten:
Mit der folgenden Erfassungsmethode können Sie mehrdeutige Where-Zustände auf einfache Weise beheben:
addFilterToMap($filterName, $alias, $group = 'fields')
$filter
- Es ist der Name des Filters, der in deraddFieldToFilter()
Methode verwendet wird, in Ihrem Fallincrement_id
$alias
- Es ist der vollständige Name der Spalte, die dem Filter zugeordnet ist, in Ihrem Fallmain_table.increment_id
.$group
- sollte eine Karte für jede Art von Informationen in der Sammlung sein, wird aber vorerst nur in Filtern verwendet, sodass Sie dieses Argument weglassen können.Ich denke auch nicht, dass beforeLoad der richtige Ort ist, um Ihre Joins zu platzieren, es sei denn, Sie beobachten ein Ereignis. In Ihrem Fall ist es besser, die
_initSelect()
Methode mit vorherigem Aufruf zu verschiebenparent::_initSelect()
. Sie können eineaddFilterToMap()
Methode innerhalb Ihrer_initSelect()
Methode aufrufen , um Join-Konflikte zu lösen:quelle
_initSelect
wird immer nur einmal ausgeführt und_beforeLoad
kannload()
mehr als einmal aufgerufen werden, da Sie mehr als einmal sammeln können, wenn Sie den Status zurücksetzen.$collection = Mage::getModel("education/ticket") ->getCollection() ->addFilterToMap('updated_at', 'main_table.updated_at') ->addFilterToMap('created_at', 'main_table.created_at');