Bird87 ZA
Bird87 ZA

Reputation: 2160

Conditional associated models with children models CakePHP

I have the following db structure:

// Contacts
,----,------------,------------------,
| id | name       | email            |
|----|------------|------------------|
| 1  | John Doe   | [email protected] |
'----'------------'------------------'

// Jobs
,----,------------,-------------------,
| id | title      | description       |
|----|------------|-------------------|
| 1  | Fancy Job  | This job is fancy |
'----'------------'-------------------'

// JobRequests
,----,------------,------------,----------,
| id | job_id     | contact_id | accepted |
|----|------------|------------|----------|
| 1  | 1          | 1          | yes      |
| 2  | 1          | 2          | no       |
'----'------------'------------'----------'

And I want all the contacts that have accepted a job.

I've tried doing the following:

$jobs = $this->Jobs
    ->find('all')
    ->where(['event_id' => $id])
    ->contain([
        'JobRequests' => [
            function(Query $query) {
                return $query->where(['JobRequests.accepted' => 'yes']);
            },
            'Contacts'
        ]
    ]);

But then I get a {{Unsupported operand types}} error. And the docs don't really say what you should do, should you want a condition and a contain.

How would I do this?

EDIT: I want data to look like this:

Job 1:
     Accepted by John Doe
     Accepted by Jane Doe
Job 2:
     Accepted by Foo Bar
Job 3:
     Nobody accepted

Upvotes: 0

Views: 98

Answers (1)

ndm
ndm

Reputation: 60453

You are using the wrong "syntax", you can't just pass a callable inside an options array.

Further below in the docs that you've linked there's an example how to nest query builders and pass additional conditions... the queryBuilder option:

->contain([
    'JobRequests' => [
        'queryBuilder' => function(Query $query) {
            return $query->where(['JobRequests.accepted' => 'yes']);
        },
        'Contacts'
    ]
])

Stacking the containments should also work:

->contain([
    'JobRequests' => function(Query $query) {
        return $query->where(['JobRequests.accepted' => 'yes']);
    },
    'JobRequests.Contacts'
])

And nesting should work too:

->contain([
    'JobRequests' => function(Query $query) {
        return $query
            ->where(['JobRequests.accepted' => 'yes'])
            ->contain(['Contacts']);
    }
])

See also

Upvotes: 1

Related Questions