Adding new 'contain' options later

I suspect that this is an easy question to answer, I’ve been searching for quite a while and unable to find an answer.

Sometimes in my processing logic I decide that I need more information than I specified in my initial contain clause.

I would like to be able to load additional criteria later in my code.

Imagine a workflow, where this gets all the information:
$project = $this->Project->get ( $id, [‘contain’ => [‘Level1’ ,‘Level2’]] );

I suspect that I’m only processing level 1 data so most of the time I would use:
$project = $this->Project->get ( $id, [‘contain’ => [‘Level1’ ]] );

If a specific condition is met in level 1, I might need Level 2 data
$project->ZZZ_HOWDOI_ZZZ([‘contain’ => [‘Level2’ ]]);

How does the Entity add additional contains conditions after the fact?

->get executes query immediately, so what you want is

$query = $table
    ->findById($id)
    ->contain(['level1']);

if ($condition) {
    $query->contain(['level2']);
}

$query->first();

Thank you so much for taking the time to reply.

I need to be able to use the data in level 1 to determine if I need level 2.

Pardon my ignorance, i’m still learning.

$query = $this->Project
    ->findById($id)
    ->contain(['level1']);
$project=$query->first();

$condition = $this->checkLevel1ProjectData( $project );
if ($condition) {
    $query->contain(['level2']);
    $project  = $query->first();  // This does not return new data
    $condition = $this->checkLevel2ProjectData( $project );
}

Obviously I could simply create a new query, containing ‘level2’ data and execute that. However, that would since I’m using expensive queries to the database (not simple query I used as an example) I don’t want to do that if I don’t have to .

Additionally, I could manually go out and get the level2 data using additional queries, but, the elegance of cake makes me think that someone has already figure this problem out.

you have executed the query

$query = $this->Project
    ->findById($id)
    ->contain(['level1']);
$project=$query->first();

thats why when you execute it 2nd time you get same result, so you have to get new query by creating with ->findById or clone it before first execution

Thanks again for your reply.

Obviously I could simply run a new version of the query after discovering that I need more information. Or, I can just get every piece of information that I might ever need, initially without ever needing the second query.

For the purposes of an example, I’ve intentionally made things very simple.

In reality, my queries are very complicated and returning a lot of data.

When I get more data, I don’t want to discard the data I’ve already gotten, I just want to query for the additional information.

I’m trying to keep my SQL costs as low as possible, by not querying the same data twice.

I have successfully added a function to the element to go back out to the table, issue a second query using just the return set from the second set of data, then copy over the results from the second element into the first element, but, that seems messy.

I was hoping for a better way.