nextras / orm

Orm with clean object design, smart relationship loading and powerful collections.
https://nextras.org/orm
MIT License
310 stars 57 forks source link

Class '<Entity>' is not accepted by 'App\Model\<Entity>Repository' repository (using STI) #447

Closed Hologos closed 4 years ago

Hologos commented 4 years ago

Describe the bug I am trying to fetch STI entities from repository but I am getting error Class '<Entity>' is not accepted by 'App\Model\<Entity>Repository' repository.

To Reproduce

<?php

declare(strict_types=1);

namespace App\Model;

use Nextras\Orm\Entity\Entity;
use Nextras\Orm\Relationships\ManyHasMany;

/**
 * @property int                      $id          {primary}
 * @property string                   $name
 * @property int                      $type        {enum self::TYPE_*}
 * @property ManyHasMany|Customer[]   $customers   {m:m Customer::$benefits}
 */
abstract class Benefit extends Entity
{
    const TYPE_BYPASS_ORDER_CONDITION_BENEFIT = 1;
}

/**
 * @property Customer $customer  {m:1 Customer, oneSided=true}
 */
class BypassOrderConditionBenefit extends Benefit
{
}

public function test(): Nextras\Orm\Collection\ICollection
{
    return $this->orm->benefits->findBy([
        'type' => Benefit::TYPE_BYPASS_ORDER_CONDITION_BENEFIT,
        'Benefit->customer->id' => 1,
    ]);
}

final class BenefitsRepository extends Repository
{
    public static function getEntityClassNames(): array
    {
        return [ Benefit::class, BypassOrderConditionBenefit::class ];
    }

    public function getEntityClassName(array $data): string
    {
        switch ($data['type'])
        {
            case Benefit::TYPE_BYPASS_ORDER_CONDITION_BENEFIT:
                return BypassOrderConditionBenefit::class;

            default:
                throw new \InvalidArgumentException('Unknown benefit type '. $data['type'] .'.');
        }
    }
}

Stack trace exception--2020-08-17--09-16--de1c0f5456.html.zip.

Expected behavior To be able to fetch those entities.

Versions::

hrach commented 4 years ago

Oh, this is not a bug, but a feature. You have to use FQN class name.

public function test(): Nextras\Orm\Collection\ICollection
{
    return $this->orm->benefits->findBy([
        'type' => Benefit::TYPE_BYPASS_ORDER_CONDITION_BENEFIT,
        Benefit::class . '->customer->id' => 1,
    ]);
}