Skip to content

Conversation

@dereuromark
Copy link
Member

Resolves comments and 6.x roadmap of
#17547

Supported Formats:

  // Old format (still supported)
  ['associated' => ['Articles' => ['associated' => ['Users', 'Comments']]]]

  // New unified format (like contain())
  ['associated' => ['Articles' => ['Users', 'Comments']]]

  // Dot notation (always supported)
  ['associated' => ['Articles.Users', 'Articles.Comments']]

But this PR could actually go into 5.next, since it seems "BC".
In 6.x we could then think about removing one of the different declarations.

@dereuromark dereuromark added this to the 6.0 milestone Oct 23, 2025
@dereuromark dereuromark requested a review from markstory October 23, 2025 04:10
}

/**
* Returns the list of known option keys that should not be treated as associations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I actually prefer the use of the associated key, you don't have to maintain this list of known keys.

@markstory
Copy link
Member

In 6.x we could then think about removing one of the different declarations.

How? It seems like only one of them provides the full feature set. The other forms are for 'simple' cases. Maybe we could remove the 'dot notation' form, but I think that is also supported by contain().

@dereuromark
Copy link
Member Author

dereuromark commented Oct 28, 2025

Yeah, now they are now equal in support with this.
If we want dot notation removed, we would probably want to deprecate that on the contain() part too.

@ADmad
Copy link
Member

ADmad commented Oct 28, 2025

My issue isn't really with the dot notation. It's with array structure like this where the aliases and config keys can be mixed at the same level:

$usersQuery->contain([
    'Articles' => [
        'conditions' => [.....],   // option key
        'Comments',  // model alias
    ],
]);

I would prefer if the 2nd level associations were also under the config key:

$usersQuery->contain([
    'Articles' => [
        'conditions' => [.....],
        'associated' => ['Comments']
    ],
]);

@markstory
Copy link
Member

I can agree that

$usersQuery->contain([
    'Articles' => [
        'conditions' => [.....],   // option key
        'Comments',  // model alias
    ],
]);

is awkward. I'm on-board for not having that anymore. Would it suffice to deprecate only this call style in 5.x? That would allow us to remove the problematic scenario with a graceful upgrade path.

It looks like this call style can be detected by having a mix of string and int keys which should be simple enough to detect. I think this also sets us up better for contain options to use a builder pattern more easily in the future.

@dereuromark
Copy link
Member Author

If aliases were always UpperCaseCamel (upper case first letter), there would also be no collisions.
Same if all other keys would be underscored, e.g. _conditions etc.
But otherwise I agree that we should not use that mixed format anymore.

@ADmad
Copy link
Member

ADmad commented Oct 29, 2025

Would it suffice to deprecate only this call style in 5.x?

I would be happy with just that.

It looks like this call style can be detected by having a mix of string and int keys which should be simple enough to detect.

Not always, I think you can have this form too:

$usersQuery->contain([
    'Articles' => [
        'conditions' => [.....],   // option as key
        'Comments' => [..options for this inner model...]  // model alias as key
    ],
]);

I think this also sets us up better for contain options to use a builder pattern more easily in the future.

Yes, adding builders in future would be nice. I believe that will also make it easier for AI agents to write CakePHP code.

If aliases were always UpperCaseCamel (upper case first letter), there would also be no collisions.

Yes when naming the aliases as per convention the chances of collision are negligible but it's also about readability. I personally find that this mix of options and alias as same level adds unnecessary cognitive load.

Resolved conflict in src/ORM/Marshaller.php by keeping both changes:
- Documentation for new nested array format (from PR)
- Template type annotations (from 6.x)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@dereuromark
Copy link
Member Author

So what course do we go?
What exactly do we deprecated, what do we propose people use?

@othercorey
Copy link
Member

Is the proposal to check if the isn't isn't one of the allowed option keys and if so suggest using associated ?

@dereuromark
Copy link
Member Author

My main concern would be that this verbose form is super hard to type for default case when u just want list them nested.
I hope we find another agreement on shortcutting.

@othercorey
Copy link
Member

Is is annoying. I'm not sure how to improve it with fluid getters other than with a closure - but we already do that to modify the query.

@dereuromark
Copy link
Member Author

The few times you need to set options, I would in this syntax prefer underscores. We could throw deprecations in 5.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants