chrisShick
chrisShick

Reputation: 1096

Cakephp 3 dynamically build contain

How can I dynamically build the contain in the new cakephp 3 query builder. This is what I have now:

$query = $dbTable->find()
                ->select($contain['select']['fields'])
                ->contain(function($q) use($array,$contain){
                      $new = [];
                      foreach($array as $v){
                        if(isset($contain['contains'][$v])){
                          $fields = $contain['contains'][$v];
                          $new[$v] = $q->select($fields);
                         }
                      }
                      return $new;
                  });

But I am getting several errors with this:

Warning (2): Illegal offset type in isset or empty [CORE\src\ORM\EagerLoader.php, line 198]
Warning (2): strpos() expects parameter 1 to be string, object given [CORE\src\ORM\EagerLoader.php, line 203]
Warning (2): Illegal offset type [CORE\src\ORM\EagerLoader.php, line 223]
Warning (2): Illegal offset type [CORE\src\ORM\EagerLoader.php, line 224]

Upvotes: 1

Views: 2083

Answers (3)

Bruny
Bruny

Reputation: 39

To get all fields in the table Articles do this in your controller.

$query = $this->modelName->find('all')
                   ->contain('Articles');

If you want a expecify field use this:

$query = $this->modelName->find('list', [
    'keyField' => 'id',
    'valueField' => 'author.name'
])->contain(['Articles']);

To more informations about: https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html

Upvotes: 0

ndm
ndm

Reputation: 60463

As already mentioned by Lorenzo, that's not how it works, contain() doesn't accept callables, just look at the docs:

http://api.cakephp.org/3.0/class-Cake.ORM.Query.html#_contain

Also your code would invoke select() multiple times on one and the same query, that wouldn't work anyways.

However, looking at your code it seems that you could simply make use of the fields option, ie build a simple array to pass to contain(). This is shown in the docs, the example however will trigger an error as it seems to be necessary to explicitly set the foreign key field too:

$query->contain([
    'Articles' => [
        'fields' => ['foreign_key_column_name', 'title']
    ]
]);

Upvotes: 2

You cannot use contain with a closure inside. If you believe this is a good idea (I think it could be) then open a enhancement request on github.

Upvotes: 1

Related Questions