Magento 2 - bidang kisi admin kustom - kesalahan saat menyortir atau memfilter

9

Saya menambahkan kolom khusus ke admin grid, seperti ini

<column name="customer_name" class="Vendor\Module\Ui\Component\Listing\Columns\CustomerName">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

Di kelas CustomerName saya, saya membuat nilai untuk kolom ini:

public function prepareDataSource(array $dataSource)
{
    $fieldName = $this->getData('name');
    foreach ($dataSource['data']['items'] as & $item) {
        $customer = $this->customerRepository->getById($item['customer_id']);
        $name = $customer ? $customer->getFirstName().' <'.$customer->getEmail().'>' : '';
        $item[$fieldName] = $name;
    }
    return $dataSource;
}

Itu ditampilkan di grid seperti yang diharapkan. Tetapi ketika saya mencoba mengurutkan berdasarkan kolom atau filter ini - terjadi kesalahan

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'customer_name' in 'order clause'

Bagaimana saya bisa memperbaikinya?

MEMPERBARUI

Sekarang saya mencoba menyelesaikan masalah ini dengan menghapus kelas CustomerName (dan menghapus referensi dalam tag kolom di xml) dan sebagai gantinya saya menambahkan fungsi _renderFiltersBefore () di kelas koleksi saya

 protected function _renderFiltersBefore() {
     $joinTable = $this->getTable('customer_entity');
     $this->getSelect()->join($joinTable.' as customer_entity','main_table.customer_id = customer_entity.entity_id', array('*'));
     $this->getSelect()->columns('CONCAT(firstname," <",email,">") as customer_name');
     parent::_renderFiltersBefore();
}

Sekarang penyortiran berfungsi, tetapi penyaringan tidak (dapatkan kesalahan yang sama)

Anna
sumber

Jawaban:

13

Ada metode pabrik yang dapat Anda gunakan, dan ini adalah addFilterToMap(). Di mana filter render Magento 2 baru saja mengganti subjek dari kondisi berdasarkan bidang yang dipetakan

Anda dapat menyebutnya baik dalam _initSelect atau _renderFiltersBefore metode.

untuk kolom sederhana yang sudah ada dalam seleksi (bagus untuk menyelesaikan kesalahan ambigu)

$this
     ->addFilterToMap('customer_id', 'ce.entity_id');

tetapi dalam kasus Anda perlu memetakan ekspresi sebagai

$this
    ->addFilterToMap(
       'customer_name ', 
       new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")')
    ); 

jadi bagian kondisi dari kueri akan ... WHERE (CONCAT(ce.firstname," <",ce.email,">") LIKE '%@yippie.com%') ... bukannya ... WHERE (customer_name LIKE '%@yippie.com%') ...

Anda juga dapat menggunakan metode pabrik terkait koleksi lain untuk menggunakan ekspresi di SELECTbagian dari kueri

$this
    ->addExpressionFieldToSelect(
        'firstname',
        new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")'),
        []
    )

dari pada

$this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');
Mammouth
sumber
Terima kasih banyak! Sedang berjuang dengan ini selama setengah hari. Di mana Anda menemukan / mempelajari ini? Tentunya, bukan di dokumen?
Jānis Elmeris
seperti posting asli yang disebutkan: harus menambahkan kolom khusus ke kisi admin - dengan opsi filter dan urutkan. Biaya sekitar 1,5 hari untuk mengetahuinya (ofc dengan jejak kaki paling sedikit)
Mammouth
Saya mencoba menampilkan faktur dan pesanan penjualan increment_ids pada modul admin modul khusus saya dengan id kenaikan pesanan penjualan dilabel ulang sebagai 'ordincrementid'. Masih bahkan saya telah menggunakan addFilterToMap (); saya tidak dapat memfilter increment_id pesanan penjualan. Itu mengembalikan kesalahan ini => Kolom 'increment_id' di mana klausa ambigu
Tanyakan Bytes
6

Butuh beberapa waktu, tetapi saya menemukan jawabannya

Dalam daftar xml saya:

<column name="firstname">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

Di Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel \ Grid:

/**
 * adding email to customer name column
 */
protected function _initSelect()
{
    parent::_initSelect();
    $this->getSelect()->joinLeft(
        ['ce' => $this->getTable('customer_entity')],
        'main_table.customer_id = ce.entity_id',
        ['*']
    );

    $this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');
    return $this;
}

Dalam Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel

/**
 * addding ability to filter by column with customer name and email
 */
protected function _renderFiltersBefore()
{
    $wherePart = $this->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE);
    foreach ($wherePart as $key => $cond) {
        $wherePart[$key] = str_replace('`firstname`', 'CONCAT(firstname," <",email,">")', $cond);
    }
    $this->getSelect()->setPart(\Magento\Framework\DB\Select::WHERE, $wherePart);
    parent::_renderFiltersBefore();
}
Anna
sumber