Kyle Weishaupt
Kyle Weishaupt

Reputation: 99

CakePHP custom finder for belongsToMany association

I'm having trouble applying a custom finder from a behavior on the join table for a belongsToMany association with CakePHP 3.x.

My main model Assessment can have numerous UnableToCompleteReasons and I use the muffin/trash behavior for soft-delete support on the join table AssessmentUtcReasons.

    $this->belongsToMany('UnableToCompleteReasons', [
        'joinTable' => 'AssessmentUtcReasons',
        'foreignKey' => 'AssessmentLogId',
        'targetForeignKey' => 'UtcReasonId',
        'through' => 'AssessmentUtcReasons',
        'saveStrategy' => 'replace',
    ]);

The association technically works just fine here. Removed UnableToCompleteReasons associations are not returned to the Assessment model as you'd expect.

My issue is that I have to return the deleted records as well, including all the join data, and I can't figure out using the withTrashed finder from the muffin/trash behavior that is on my AssessmentUtcReasons table object.

When I use my full finder, I want to apply the withTrashed finder to the join table - since the UnableToCompleteReasons table doesn't use soft-delete.

Here's essentially what I'm going for:

public function findFull(Query $query, $options)
{
    return $query->contain([
            'UnableToCompleteReasons' => function ($q) {
                // These finders should be on the JOIN table
                return $q->find('withTrashed')->find('ordered');
            },
        ]);     
    }
}

I've tried everything I can think of, such as using the finder option on the association but everything seems to only apply to the other table and not the join table.

I can't find anything in the documentation for this either so please excuse me if I missed something. Thanks!

Upvotes: 1

Views: 449

Answers (1)

ndm
ndm

Reputation: 60463

I think you'll find yourself either creating concrete associations with your join table, ie a Assessment hasMany AssessmentUtcReasons association, so that you can contain the join table association directly, like:

$query->contain([
    'AssessmentUtcReasons' => function ($q) {
        return $q
            ->find('withTrashed')
            ->find('ordered')
            ->contain('UnableToCompleteReasons');
    },
]);

or, if applicable, moving the behaviors/finders into the UnableToCompleteReasons table class.

Upvotes: 2

Related Questions