omines / datatables-bundle

DataTables bundle for Symfony
https://omines.github.io/datatables-bundle/
MIT License
258 stars 115 forks source link

ORMAdapter and single_table_inheritance #81

Closed lemorragia closed 4 years ago

lemorragia commented 5 years ago

Hi, i'm trying datatables-bundle and maybe i stumbled upon an issue.

I'm using doctrine single_table inheritance to implement this kind of behaviour:

BusinessPartner <-single_table inheritance With

are the three extending classes (as a company buying from vendors and selling to companies and privates as customers)

The bundle seems to have a strange behaviour customizing the criteria for the ORM adapter.

->createAdapter(ORMAdapter::class, [ 'entity' => BusinessPartner::class, ])

works with no issues. Pagination, ordering and global search too are working. But as i try to implement the logic "get me all customers", which works in a normal doctrine query:

->createAdapter(ORMAdapter::class, [
    'entity' => BusinessPartner::class,
    'criteria' => [
        function (QueryBuilder $builder) use ($entityManager){
            $builder->select('c');
            $builder->from(BusinessPartner::class,'c');
            $builder->andWhere(
                ('c INSTANCE OF :organizationClass OR c INSTANCE OF :personClass')
            )
            ->setParameter('organizationClass',  $entityManager->getClassMetadata(Organization::class))
            ->setParameter('personClass',  $entityManager->getClassMetadata(Person::class));
        },
        new SearchCriteriaProvider(),
    ],
])

the table is displayed but pagination and search are completely scrambled. Search results seems random(inputting data in the search field filters something but not what is typed) and debugging the DataTables pagination gives me: "Showing 1 to 20 of 252,500 entries (filtered from 505 total entries)" (total database entries in the BusinessPartner table is 505...so organization+person must be a subset of that number).

Am i missing something in the configuration, or i stumbled upon an issue for a usage the bundle was never intented?

giovannialbero1992 commented 5 years ago

Have you tried to remove $builder->select(... and $builder->from(... ? And have you tried to set Parameter with strings Person::class and Organization::class?

I think that you don't need to add new SearchCriteriaProvider() to array criteria

lemorragia commented 5 years ago

@giovannialbero1992

yes. Removing the select,from clauses throws an error about not finding an alias for the querybuilder 'c'. Removing the getClassMetadata with the INSTANCE OF clauses causes no matches in the query. Removing the SearchCriteriaProvider has no effect on the problem (but i think is needed if the global search has to work with normal parameters plus the additional "customer-where-clause"...right?).

I also tried with the alternative doctrine syntax $qb->andWhere($qb->expr()->isInstanceOf('f', Person::class)); with same results

lemorragia commented 5 years ago

I "kinda" solved the problem overriding the "query" parameter of the table instantiation...as far as i understand it, this will probably create problems with global and column searching

shades684 commented 4 years ago

Basically you're rewiring the whole query mechanism. The criteria should contain the criteria part of the query. In your case:

   $builder->andWhere(
                ('businessPartner INSTANCE OF :organizationClass OR businessPartner  INSTANCE OF :personClass')
            )
            ->setParameter('organizationClass',  $entityManager->getClassMetadata(Organization::class))
            ->setParameter('personClass',  $entityManager->getClassMetadata(Person::class));