Devil of a time saving relation to associated data on create

I have an entity, Team, with four Contacts (each having a special role). Let’s say one is Captain and the other is Waterboy.

I set up Team as hasOne Captain and hasOne Waterboy (and then hasOne for the other two roles as well). I used the extended form in order to create more than one hasOne relationship for the same className.

I have a form where the user can edit the team contact information, including the four Contacts’ email, names, phones, etc. The form is a Team form that submits to the Team controller.

For whatever reason I can’t understand, saving the form creates the new contacts but doesn’t update the Captain_id or the Waterboy_id (or any of the 4) for the corresponding Teaem record in my Teams table, which remain null after the save and the data never loads again when I want to edit the data.

I’ve been through the documentation and tried creating new entities for each Contact and then assigning it to the Team entity, but that did nothing. I can add or remove that code and nothing changes. So I’m not sure it has any effect:

$captain = $this->Teams->CaptainContacts->newEntity();

This doesn’t work:

The Cookbook is categorically wrong on the matter of saving (hasOne) associated data when the associated data is new. The id of the associated data never gets stored in the fk field of the main entity.

So now I’m trying to do this by hand, the long way. That means saving the associated data, obtaining the id that was generated, and then preparing a whole new request->data array for my main entity and manually adding the id, then saving that.

All the magic “dirty” and “new” keys are worth nothing here.

And for what it’s worth, as I said before, the 3.x cookbook is really pretty bad compared to previous cookbooks. The chapter on saving data is ginormous and waxes philosophically on that is happening with flow charts, and makes references to new and unknown concepts like “marshaling” without linking to it or saying when or why you would need it. Then there’s the matter of incredibly inconsistent use the main entity handle, like this:

$articlesTable = TableRegistry::get('Articles');
$tag1 = $articlesTable->Tags->findByName('cakephp')->first();
$tag2 = $articlesTable->Tags->newEntity();
$tag2->name = 'awesome';
$article = $articlesTable->get(12);
$article->comments = [$firstComment, $secondComment];
$article->tags = [$tag1, $tag2];

When other pages use the alternative format like this:


And nowhere does it tell you to use patchEntity even though every single create/update action written by bake uses it. The documentation suffers from a combination of over-explaining some things that are niche or advanced while glossing over things that every developer who needs something more than bake or the tutorial is going to need to understand. Some things in the example code are arbitrarily left out because “we should know they should be there fro reading xxx chapter elsewhere” while other things that seem superfluous to me at least are included. Most examples leave me scratching my head trying to decipher what are the salient bits.

Honestly, if you’re trying to figure out Cake 3.0 you can either try using the (limited in scope) tutorial, or bake everything and then try to modify it to your needs, or read the documentation cover to cover and hope it all sticks as you dive into your project because none of those three sources map very well to another.

I’m frustrated because I’m having to run to this forum for like every little thing now that I would expect to be more automagic or at least coherently explained.