luya-module-admin icon indicating copy to clipboard operation
luya-module-admin copied to clipboard

ngRestRelations displays records only from first pool

Open jettero777 opened this issue 5 years ago • 5 comments

What steps will reproduce the problem?

ngRestRelations used for linked records which have several ngRestPools

What is the expected result?

all child records being shown in list view

What do you get instead? (A Screenshot can help us a lot!)

list with child records only from first pool (which goes first in menu)

jettero777 avatar Feb 14 '20 08:02 jettero777

could you please post your config/models and the sub relation your are talking about? so i can clearly see what your configuration is and i can try to reproduce.

nadar avatar Feb 16 '20 13:02 nadar

@nadar here I created minimal config to show it

tables

CREATE TABLE bar (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  name varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE foo (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  bar_id int(10) unsigned NOT NULL DEFAULT 0,
  type tinyint(1) unsigned NOT NULL DEFAULT 1,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

in module

    public $apis = [
        'api-test-bar' => 'app\modules\test\backend\apis\BarController',
        'api-test-foo' => 'app\modules\test\backend\apis\FooController',
    ];

    public function getMenu()
    {
        return (new \luya\admin\components\AdminMenuBuilder($this))
        ->node('Test', 'settings')
            ->group('Test')
                ->itemApi('Bar', 'testadmin/bar/index', 'settings', 'api-test-bar')
                ->itemPoolApi('Foo1', 'testadmin/foo/index', 'settings', 'api-test-foo', 'pool1')
                ->itemPoolApi('Foo2', 'testadmin/foo/index', 'settings', 'api-test-foo', 'pool2');
    }

Bar model

<?php
namespace app\modules\test\models;

use luya\admin\ngrest\base\NgRestModel;

/**
 * @property int $id
 * @property string $name
 */
class Bar extends NgRestModel
{
    public static function tableName()
    {
        return 'bar';
    }

    public static function ngRestApiEndpoint()
    {
        return 'api-test-bar';
    }

    public function ngRestAttributeTypes()
    {
        return [
            'name' => 'text'
        ];
    }

    public function rules()
    {
        return [
            [['name'], 'string'],
        ];
    }

    public function ngRestScopes()
    {
        return [
            ['list', ['name']],
            [['create', 'update'], ['name']],
            ['delete', true],
        ];
    }

    public function ngRestRelations()
    {
        return [
            [
                'label' => 'Foo',
                'targetModel' => Foo::class,
                'dataProvider' => $this->getFoos()
            ],
        ];
    }

    public function getFoos()
    {
        return $this->hasMany(
            Foo::class, ['bar_id' => 'id']
        );
    }
}

Foo model

<?php
namespace app\modules\test\models;

use luya\admin\ngrest\base\NgRestModel;

/**
 * @property int $id
 * @property int $bar_id
 * @property int $type
 */
class Foo extends NgRestModel
{
    public static function tableName()
    {
        return 'foo';
    }

    public static function ngRestApiEndpoint()
    {
        return 'api-test-foo';
    }

    public function ngRestAttributeTypes()
    {
        return [
            'bar_id' => [
                'selectModel',
                'modelClass' => Bar::class,
                'valueField' => 'id',
                'labelField' => 'name',
            ],
            'type' => [
                'selectArray',
                'data' => [
                    '1' => 'one',
                    '2' => 'two',
                ],
                'initValue' => '1',
            ],
        ];
    }

    public function rules()
    {
        return [
            [['bar_id', 'type'], 'integer'],
        ];
    }

    public function ngRestScopes()
    {
        return [
            ['list', ['bar_id', 'type']],
            [['create', 'update'], ['bar_id', 'type']],
            ['delete', true],
        ];
    }

    public function ngRestPools()
    {
        return [
            'pool1' => ['type' => 1],
            'pool2' => ['type' => 2],
        ];
    }
}

If you will create records in both Foo pools for the same parent Bar record and then will choose relation 'Foo' in parent Bar record, it will list not all child records but only Foo records from Pool1.

jettero777 avatar Feb 17 '20 14:02 jettero777

So i would say the expected result is that

public function ngRestRelations()
    {
        return [
            [
                'label' => 'Foo',
                'targetModel' => Foo::class,
                'dataProvider' => $this->getFoos()
            ],
        ];
    }

should list all items for this model? Wether they are in a certain pool or not.

nadar avatar Feb 18 '20 07:02 nadar

@nadar yeah, in current form, as we configure 'dataProvider' => $this->getFoos() it is expected to have records from this provider as is.

It can be a feature if we can also configure a pool as a data provider, but we should be able to choose which pool to use, not just first encountered as it is currently. Or be able not to use any pool but show all records.

In my case the records go between pools as they being processed so they suddenly appear and disappear from the relation list :)

PS also addition to the bug: if you open Bar-Foo relation and choose to create new Foo record, then it is being created in first pool only, you can't choose 'type'=2 in above example, as the field not displayed.

jettero777 avatar Feb 18 '20 16:02 jettero777

Maybe a similar cause as in #455 - missing second parameter pool in a getApiDetail(apiEndpoint) call?

hbugdoll avatar Nov 02 '21 10:11 hbugdoll