Magento 2-カスタム管理グリッドフィールド-並べ替えまたはフィルタリング時のエラー


9

このように、管理グリッドにカスタム列を追加しました

<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>

私のCustomerNameクラスで、この列の値を作成します。

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

予想通りグリッドに表示されます。しかし、この列またはフィルターでソートしようとすると、エラーが発生します

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

どうすれば修正できますか?

更新

ここで、CustomerNameクラスを削除して(そしてxmlの列タグ内の参照を削除して)この問題を解決しようとしましたが、代わりにコレクションクラスに_renderFiltersBefore()関数を追加しました

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

現在、ソートは機能していますが、フィルタリングは機能しません(同じエラーが発生します)

回答:


13

使用できるファクトリメソッドがあり、これがaddFilterToMap()です。Magento 2レンダリングフィルターは、マップされたフィールドに基づいて条件の対象を置き換えるだけです。

_initSelectまたは_renderFiltersBeforeメソッドで呼び出すことができます。

選択に既に存在する単純な列の場合(あいまいなエラーを解決するのに適しています)

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

しかし、あなたの場合、式を次のようにマップする必要があります

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

そのクエリの条件の一部になります ... WHERE (CONCAT(ce.firstname," <",ce.email,">") LIKE '%@yippie.com%') ... の代わりに、 ... WHERE (customer_name LIKE '%@yippie.com%') ...

また、他のコレクション関連のファクトリメソッドを使用してSELECT、クエリの一部で式を使用することもできます

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

の代わりに

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

どうもありがとう!これに半日も苦しんでいました。どこでこれを見つけましたか/学びましたか?確かに、ドキュメントにはありませんか?
ジャニスElmeris

元の投稿で述べたように、カスタムカラムを管理グリッドに追加する必要がありました-フィルターと並べ替えのオプションがあります。それを理解するのに約1.5日かかります(ofcは最小のフットプリント)
Mammouth

カスタムモジュール管理グリッドに請求書と販売注文の両方のincrement_idを表示しようとしていますが、販売注文のインクリメントIDは「ordincrementid」というラベルに変更されています。それでも、私はaddFilterToMap()を使用していました。販売注文のincrement_idをフィルタリングできません。このエラーを返す=> where句の列 'increment_id'があいまいです
Ask Bytes

6

少し時間がかかりましたが、わかりました

私のxmlリストでは:

<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>

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

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();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.