CakePHP 3.x translation behavior: read all translations with "get"

131 Views Asked by At

The cookbook describes how to retrieve all translations for an entity, but it's using find('translations'). It also discusses how to retrieve all translations for associations. I am hoping to blend these, using get and the containment functionality, because I'm already reading associated records at the same time.

To load a league, and all associated divisions with their translations, this works:

$league = $this->Leagues->get($id, ['contain' => [
    'Divisions' => [
        'queryBuilder' => function (Query $q) {
            return $q->find('translations');
        },
    ],
]]);

So far, so good. But I need to load all the translations for the league as well. This works:

$league = $this->Leagues->find('translations')->where(['Leagues.id' => $id])->contain([
    'Divisions' => [
        'queryBuilder' => function (Query $q) {
            return $q->find('translations');
        },
    ],
])->first();

but it's inconsistent with all my other code for reading a single entity, which always uses get. I tried this:

$league = $this->Leagues->get($id, ['contain' => [
    'queryBuilder' => function (Query $q) {
        return $q->find('translations');
    },
    'Divisions' => [
        'queryBuilder' => function (Query $q) {
            return $q->find('translations');
        },
    ],
]])->first();

but it results in "Error: Cannot use object of type Closure as array" from EagerLoader::normalized.

Am I missing something obvious (or not so obvious?), or is this not a supported option?

1

There are 1 best solutions below

1
On BEST ANSWER

queryBuilder is an option for an actual containment, you can't use it as a top level key.

What you are looking for is the get() method's finder option:

$league = $this->Leagues
    ->get($id, [
        'finder' => 'translations',
        'contain' => [
            'Divisions' => [
                'queryBuilder' => function (Query $q) {
                    return $q->find('translations');
                },
            ],
        ]
    ])
    ->first();

See also