atk4 / data

Data Access PHP Framework for SQL & high-latency databases
https://atk4-data.readthedocs.io
MIT License
273 stars 46 forks source link

AggregateModel: Cannot add hasOne reference #984

Closed mkrecek234 closed 2 years ago

mkrecek234 commented 2 years ago

The recent implementation of AggregateModel does not allow to add a hasOne reference (or inherit it from the source model). Steps to replicate:

 $aggregateModel =  new \Atk4\Data\Model\AggregateModel($sourcemodel);

        $aggregateModel->hasOne('tax_rule_id', ['model' => [TaxRule::class]]);

        $aggregateModel->setGroupBy(['tax_rule_id', 'tax_rate'], [
            'total_gross'                 => ['expr' => 'sum([total_gross])'],
            'total_net'                   => ['expr' => 'sum([total_net])'],
            'total_tax'                   => ['expr' => 'sum([total_tax])'],
        ]);

Expected result: $targetmodel->ref('tax_rule_id') returns hasOne-linked model.

Result: Error in vendor/atk4/data/src/Reference.php:224saying TypeError: preg_quote(): Argument #1 ($str) must be of type string, null given

mkrecek234 commented 2 years ago

@mvorisek with the recent changes, then the error changes to !! ATK4 CORE ERROR - EXCEPTION RENDER FAILED: Atk4\Data\Exception: AggregateModel model does not support this action !!

mvorisek commented 2 years ago

The exception render issue is fixed in https://github.com/atk4/core/pull/347

the exception itself is valid, here is a repro using atk4/ui demo models:

$product = new Product($app->db);

$aggregate = new AggregateModel($product);
$aggregate->hasOne($product->fieldName()->product_category_id, ['model' => [Product::class]]);
$aggregate->setGroupBy([$product->fieldName()->product_category_id], [
    's' => ['expr' => 'count(*)'],
]);

$aggregate->loadAny()->ref($product->fieldName()->product_category_id);