Um pouco de contexto para isso. Quero estender a função de exportação de pedidos de vendas (via grade) para ter mais colunas. Eu criei um módulo que adiciona uma nova grade para exportação e também um novo modelo de coleção que estende o original. Isso usa a função _beforeLoad () para que eu possa ingressar nas tabelas necessárias.
O problema que estou tendo é que, quando os filtros da grade são adicionados (o increment_id, a data do pedido etc.), a cláusula where que isso adiciona não prefixa a tabela e estou tendo problemas com nomes de colunas ambíguos. Por exemplo, em increment_id, estou tendo o problema na 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 é adicionada antes que eu faça as junções às outras tabelas na função _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 um breve teste, mudei a linha para
$this->getCollection()->addFieldToFilter('main_table.' . $field , $cond);
e isso funcionou, mas não é uma ótima maneira de fazê-lo.
Meu código em _beforeLoad () é
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();
}
Preciso usar o increment_id para ingressar na tabela de grade de pedidos de vendas e na tabela de transações SagePay, pois esse é o único ID comum que posso ver.
Basicamente, estou me perguntando qual é a melhor abordagem para lidar com isso. Provavelmente eu poderia fazer a alteração mencionada acima, mas isso não parece certo. Existe algo que eu possa mudar nas minhas declarações de associação?
Obrigado.
Respostas:
Você pode resolver facilmente qualquer condição where ambígua usando o seguinte método de coleta:
addFilterToMap($filterName, $alias, $group = 'fields')
$filter
- é o nome do filtro usado noaddFieldToFilter()
método, para o seu caso éincrement_id
$alias
- é o nome completo da coluna que está associada ao filtro, para o seu casomain_table.increment_id
.$group
- foi planejado para ser um mapa para qualquer tipo de informação na coleção, mas por enquanto é usado apenas em filtros, para que você possa omitir esse argumento.Também não acho que beforeLoad seja o lugar certo para você se unir, a menos que esteja observando um evento. No seu caso, é melhor movê-lo para o
_initSelect()
método com a chamada anteriorparent::_initSelect()
. Você pode chamar oaddFilterToMap()
método dentro do seu_initSelect()
método para resolver conflitos de junção, assim:fonte
_initSelect
é executado apenas uma vez o tempo todo,_beforeLoad
pode ser chamado mais de uma vez, pois você podeload()
coletar mais de uma vez se redefinir seu estado.$collection = Mage::getModel("education/ticket") ->getCollection() ->addFilterToMap('updated_at', 'main_table.updated_at') ->addFilterToMap('created_at', 'main_table.created_at');