Xung đột trong mệnh đề where với tên cột không rõ ràng


28

Một chút bối cảnh cho việc này. Tôi muốn mở rộng chức năng xuất đơn đặt hàng bán hàng (thông qua lưới) để có nhiều cột hơn. Tôi đã tạo ra một mô-đun bổ sung một lưới mới để xuất và cũng là một mô hình bộ sưu tập mới mở rộng bản gốc. Cái này sử dụng hàm _b BeforeLoad () để tôi có thể tham gia các bảng mà tôi cần.

Vấn đề mà tôi gặp phải là khi các bộ lọc từ lưới được thêm vào (gia số_id, ngày đặt hàng, v.v.), mệnh đề mà phần bổ sung này không thêm tiền tố vào bảng và tôi gặp vấn đề với tên cột không rõ ràng. Ví dụ: trên gia tăng_id tôi gặp vấn đề trong mệnh đề 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`

Mệnh đề này được thêm vào trước khi tôi thực hiện các phép nối với các bảng khác trong hàm _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;
    }

Như một thử nghiệm ngắn, tôi đã thay đổi dòng thành

$this->getCollection()->addFieldToFilter('main_table.' . $field , $cond);

và điều này đã làm việc nhưng nó không cảm thấy một cách tuyệt vời để làm điều đó.

Mã của tôi trong _b BeforeLoad () là

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();
}

Tôi phải sử dụng lũy ​​tiến_id để tham gia bảng lưới đơn đặt hàng bán hàng và bảng giao dịch SagePay vì đó là ID phổ biến duy nhất tôi có thể thấy.

Về cơ bản tôi đang tự hỏi cách tiếp cận tốt nhất là gì để giải quyết vấn đề này. Tôi có thể có thể thoát khỏi việc thực hiện thay đổi mà tôi đã đề cập ở trên nhưng điều đó không đúng. Có bất cứ điều gì tôi có thể thay đổi trong tuyên bố tham gia của tôi?

Cảm ơn.


1
Làm thế nào bạn tham gia các bảng? Làm việc trên mô hình Zend_Db_Select là một ý tưởng tồi, bởi vì magento ghi lại các bảng chung và thêm bình thường tất cả các tiền tố. Tôi đã viết một bài viết trên blog về việc tham gia, có thể nó giúp: blog.fabian-blechschmidt.de/articles/ Kẻ
Fabian Blechschmidt

Cảm ơn bạn đã phản hồi, tôi sẽ có một đọc về điều đó. Tôi đã thử sử dụng hàm joTable () nhưng nó không có sẵn trong mô hình bộ sưu tập.
Paul

Câu trả lời:


52

Bạn có thể dễ dàng giải quyết bất kỳ điều kiện mơ hồ nào bằng cách sử dụng phương pháp thu thập sau đây:

  • addFilterToMap($filterName, $alias, $group = 'fields')
    • $filter- đó là tên của bộ lọc được sử dụng trong addFieldToFilter()phương thức, đối với trường hợp của bạn, đó làincrement_id
    • $alias- đó là tên đầy đủ của cột được liên kết với bộ lọc, đối với trường hợp của bạn là như vậy main_table.increment_id.
    • $group - được dự định là bản đồ cho bất kỳ loại thông tin nào trong bộ sưu tập, nhưng hiện tại nó chỉ được sử dụng trong các bộ lọc, vì vậy bạn có thể bỏ qua đối số này.

Ngoài ra tôi không nghĩ rằng beforeLoad là nơi thích hợp để đặt các liên kết của bạn, trừ khi bạn đang quan sát một sự kiện. Trong trường hợp của bạn, tốt hơn là chuyển nó thành _initSelect()phương thức với cách gọi trước parent::_initSelect(). Bạn có thể gọi addFilterToMap()phương thức bên trong phương thức của mình _initSelect()để giải quyết xung đột tham gia, như thế này:

$this->addFilterToMap('increment_id', 'main_table.increment_id');

Không quan tâm, tại sao tốt hơn là thực hiện các phép nối trong _initSelect ()?
Paul

@Paul chỉ _initSelectđược thực hiện một lần mọi lúc, _beforeLoadcó thể được gọi nhiều hơn một lần, vì bạn có thể load()thu thập nhiều lần nếu bạn đặt lại trạng thái của nó.
Ivan Chepurnyi

@Paul cũng vậy, vì _b BeforeLoad có thể được gọi hai lần, bạn sẽ nhận được một lỗi nghiêm trọng từ Zend_Db_Select trong cuộc gọi thứ hai.
Ivan Chepurnyi

2
Tôi đã làm như vậy: $collection = Mage::getModel("education/ticket") ->getCollection() ->addFilterToMap('updated_at', 'main_table.updated_at') ->addFilterToMap('created_at', 'main_table.created_at');
FosAvance

@IvanChepurnyi, Là người tài giỏi. Nó phản ánh rằng bạn rất xuất sắc với tư cách là kiến ​​trúc sư Magento 1
Amit Bera
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.