Konflik di mana klausa dengan nama kolom ambigu

28

Sedikit konteks untuk ini. Saya ingin memperluas fungsi ekspor pesanan penjualan (melalui grid) untuk memiliki lebih banyak kolom. Saya telah membuat modul yang menambahkan kisi baru untuk mengekspor dan juga model koleksi baru yang memperpanjang aslinya. Ini menggunakan fungsi _beforeLoad () sehingga saya bisa bergabung dengan tabel yang saya butuhkan.

Masalah yang saya alami adalah ketika filter dari kisi ditambahkan (increment_id, tanggal pesanan, dll), klausa mana yang ditambahkan ini tidak mengawali tabel dan saya mengalami masalah dengan nama kolom yang ambigu. Sebagai contoh, pada increment_id saya mengalami masalah di mana klausa:

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`

Klausa tempat ini ditambahkan sebelum saya bergabung ke tabel lain di fungsi _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;
    }

Sebagai tes singkat, saya mengubah jalur ke

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

dan ini berhasil tetapi tidak terasa cara yang bagus untuk melakukannya.

Kode saya di _beforeLoad () adalah

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

Saya harus menggunakan increment_id untuk bergabung dengan tabel kisi pesanan penjualan dan tabel transaksi SagePay karena itulah satu-satunya ID umum yang dapat saya lihat.

Pada dasarnya saya bertanya-tanya apa pendekatan terbaik untuk mengatasi ini. Saya mungkin bisa lolos dengan melakukan perubahan yang saya sebutkan di atas tetapi rasanya tidak benar. Apakah ada yang bisa saya ubah dalam pernyataan bergabung saya?

Terima kasih.

Paul
sumber
1
Bagaimana Anda bergabung dengan tabel? Bekerja pada model Zend_Db_Select adalah ide yang buruk, karena magento merekam tabel bersama dan menambahkan secara normal semua awalan. Saya menulis artikel blog tentang bergabung, mungkin itu membantu: blog.fabian-blechschmidt.de/articles/…
Fabian Blechschmidt
Terima kasih atas tanggapannya, saya akan membacanya. Saya mencoba menggunakan joinTable () tetapi tidak tersedia dalam model koleksi.
Paul

Jawaban:

52

Anda dapat dengan mudah menyelesaikan kondisi ambigu mana pun dengan menggunakan metode pengumpulan berikut:

  • addFilterToMap($filterName, $alias, $group = 'fields')
    • $filter- itu adalah nama filter yang digunakan dalam addFieldToFilter()metode, untuk kasus Anda ituincrement_id
    • $alias- itu adalah nama lengkap dari kolom yang dikaitkan dengan filter, untuk kasus Anda main_table.increment_id.
    • $group - dimaksudkan sebagai peta untuk segala jenis info dalam koleksi, tetapi untuk saat ini hanya digunakan dalam filter, sehingga Anda dapat menghilangkan argumen ini.

Saya juga tidak berpikir bahwa beforeLoad adalah tempat yang tepat untuk bergabung, kecuali jika Anda sedang mengamati suatu acara. Dalam kasus Anda, lebih baik memindahkannya ke _initSelect()metode dengan menelepon sebelumnya parent::_initSelect(). Anda dapat memanggil addFilterToMap()metode di dalam metode Anda _initSelect()untuk menyelesaikan konflik gabungan, seperti ini:

$this->addFilterToMap('increment_id', 'main_table.increment_id');
Ivan Chepurnyi
sumber
Tidak tertarik, mengapa lebih baik melakukan join di _initSelect ()?
Paul
@ Paul _initSelecthanya dilaksanakan sekali setiap saat, _beforeLoaddapat dipanggil lebih dari satu kali, karena Anda dapat load()mengumpulkan lebih dari sekali jika Anda mengatur ulang negaranya.
Ivan Chepurnyi
@ Paul juga, karena _beforeLoad dapat dipanggil dua kali, Anda akan menerima kesalahan fatal dari Zend_Db_Pilih pada panggilan kedua.
Ivan Chepurnyi
2
Saya melakukan sesuatu seperti ini: $collection = Mage::getModel("education/ticket") ->getCollection() ->addFilterToMap('updated_at', 'main_table.updated_at') ->addFilterToMap('created_at', 'main_table.created_at');
FosAvance
@IvanChepurnyi, Apakah jenius. Ini mencerminkan bahwa Anda hebat sebagai arsitek Magento 1
Amit Bera