Un poco de contexto para esto. Quiero ampliar la función de exportación de pedidos de ventas (a través de la cuadrícula) para tener más columnas. He creado un módulo que agrega una nueva cuadrícula para exportar y también un nuevo modelo de colección que extiende el original. Esto usa la función _beforeLoad () para poder unirme a las tablas que necesito.
El problema que estoy teniendo es que cuando se agregan los filtros de la cuadrícula (el increment_id, la fecha del pedido, etc.), la cláusula where que agrega no antepone la tabla y obtengo problemas con nombres de columna ambiguos. Por ejemplo, en increment_id tengo el problema en la cláusula where:
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`
Esta cláusula where se agrega antes de hacer las uniones a las otras tablas en la función _addColumnFilterToCollection ()
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;
}
Como breve prueba, cambié la línea a
$this->getCollection()->addFieldToFilter('main_table.' . $field , $cond);
y esto funcionó pero no se siente una excelente manera de hacerlo.
Mi código en _beforeLoad () es
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();
}
Tengo que usar increment_id para unir la tabla de cuadrícula de pedidos de ventas y la tabla de transacciones de SagePay, ya que esa es la única ID común que puedo ver.
Básicamente me pregunto cuál es el mejor enfoque para abordar esto. Probablemente podría salir adelante haciendo el cambio que mencioné anteriormente, pero no me parece correcto. ¿Hay algo que pueda cambiar en mis declaraciones de unión?
Gracias.
Respuestas:
Puede resolver fácilmente cualquier condición de ambigüedad utilizando el siguiente método de recopilación:
addFilterToMap($filterName, $alias, $group = 'fields')
$filter
- es el nombre del filtro que se usa en eladdFieldToFilter()
método, para su caso esincrement_id
$alias
- es el nombre completo de la columna asociada al filtro, para su caso lo esmain_table.increment_id
.$group
- estaba destinado a ser un mapa para cualquier tipo de información en la colección, pero por ahora solo se usa en filtros, por lo que puede omitir este argumento.Además, no creo que beforeLoad sea el lugar adecuado para colocar sus uniones, a menos que esté observando un evento. En su caso, es mejor pasarlo al
_initSelect()
método con llamadas anterioresparent::_initSelect()
. Puede llamar aladdFilterToMap()
método dentro de su_initSelect()
método para resolver conflictos de unión, como este:fuente
_initSelect
se ejecuta solo una vez todo el tiempo,_beforeLoad
se puede llamar más de una vez, ya que puedeload()
recopilar más de una vez si restablece su estado.$collection = Mage::getModel("education/ticket") ->getCollection() ->addFilterToMap('updated_at', 'main_table.updated_at') ->addFilterToMap('created_at', 'main_table.created_at');