0

I am working on a subscription system. Users subscribe to Activities, but Activities have Options (different pricing options). So Users are actually linked to Options, with Subscriptions acting as join table.

Activities hasMany Options and Options hasMany Subscriptions

Now I often want a list of Subscriptions for a specific activity, regardless of options. I found that

$activity = $this->Activities->get($id, ['contain' => 'Options.Subscriptions']);

...works well to get the options which in turn contain the subscriptions. How could go about omitting the Options from the contain, such that only the Subscriptions are found?

2nd leven contain

Roberto
  • 958
  • 13
  • 33

1 Answers1

3

You'll have to ditch the idea of using containments for that task, that's not how they work, containments will always include additional data.

If you want to retrieve a models records depending on other records that may be associated with them, then you should query the target model, ie Subscriptions, and look into using the query builders association filtering methods, namely matching() and innerJoinWith().

It should be as simple as:

$query = $this->Activities->Options->Subscriptions
    ->find()
    ->matching('Options.Activities', function (\Cake\ORM\Query $query) use ($id) {
        return $query->where([
            'Activities.id' => $id
        ]);
    });

This will create a query with the required INNER joins for the associations, so that it selects only subscriptions that are associated to an option that is associated to the activity with the given id.

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • Ah, `matching` is the keyword I was looking for apparently. Would you be willing to expand your answer on how to get a list of Articles with a count of their Subscriptions? – Roberto Oct 09 '18 at 20:08
  • Nvm, found it. I added it to your answer, I hope you don't mind. – Roberto Oct 09 '18 at 20:17
  • @Roberto That's a different task, ie it's out of the scope of your original question, so I don't think it belongs in this answer. Questions and answers for this specific task already exist, for example **https://stackoverflow.com/questions/42254790/cakephp-3-count-many-to-many-association**. – ndm Oct 09 '18 at 20:46