Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter on joined columns in a collectionGridProcessor doesn't work as the COUNT(*) query removes aliases #55

Open
Mordreak opened this issue Jun 22, 2021 · 1 comment
Labels
bug Something isn't working

Comments

@Mordreak
Copy link

Steps to reproduce :

  • Create a new grid with a simple collection as a source.
  • Add a joined and aliased column from another table on the collection in a custom GridCollectionProcessor
  • Add the field as filterable in the grid xml config file
  • Try to filter the field on the magento admin frontend

/!\ I only tried this with a text field, but I guess this is the same for any other column type.

If I remember well, in the magento 1 grid builder we had to add a "filter_index" attribute on the column definition to let the grid know that it must filter with the real "table.column_name" instead of the alias.
Maybe it could be a solution

Capture d’écran 2021-06-22 à 17 30 14

@Vinai Vinai added the bug Something isn't working label Jul 1, 2021
@Vinai
Copy link
Collaborator

Vinai commented Jul 1, 2021

Wrote a test to reproduce the issue:

/**
 * @magentoDataFixture Magento/Cms/_files/block.php
 * @magentoDataFixture Magento/Cms/_files/blocks.php
 */
public function testFilterJoinedFieldonFlatTableCollection(): void
{
    $processor = new class() extends AbstractGridSourceProcessor implements HyvaGridCollectionProcessorInterface {

        /**
         * @param CmsBlockCollection $source
         * @param string $gridName
         */
        public function afterInitSelect(AbstractDbCollection $source, string $gridName): void
        {
            $select = $source->getSelect();
            // add field from joined table
            $source->getSelect()->joinLeft(
                'cms_block_store',
                'main_table.block_id = cms_block_store.block_id',
                ['test_field' => 'cms_block_store.store_id']
            );
        }
    };

    $args = [
        'gridName'            => 'test',
        'processors'          => [$processor],
        'sourceConfiguration' => ['collection' => CmsBlockCollection::class],
    ];
    /** @var CollectionGridSourceType $sut */
    $sut = ObjectManager::getInstance()->create(CollectionGridSourceType::class, $args);

    /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
    $searchCriteriaBuilder = ObjectManager::getInstance()->get(SearchCriteriaBuilder::class);
    $searchCriteriaBuilder->addFilter('test_field', '1');

    $rawGridData = $sut->fetchData($searchCriteriaBuilder->create());
    $records = $sut->extractRecords($rawGridData);
    $this->assertGreaterThan(0, count($records));
}

Considerations:

  1. Considered mapping field names to their aliases in the Navigation::getSearchCriteria view model method, but dismissed the idea because it would expose the view model to the implementation details of the underlying grid source type.
  2. The other likely solution is to use a HyvaGridSourceProcessor::beforeLoad method in \Hyva\Admin\Model\GridSourceType\CollectionGridSourceType::fetchData before the search criteria is applied to the collection. Dismissed this idea because mutating the search criteria would cause multiple loads.
  3. The next option would also be applied in \Hyva\Admin\Model\GridSourceType\CollectionGridSourceType::fetchData, but instead of using a processor, hardcode the mapping of aliases to real column names for flat table collections. This would probably involve cloning the search criteria after the processor beforeLoad methods where called to avoid duplicate loading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants