I have a hasMany
relationship (let's say Post
hasMany Comments
)
I want to edit both the Post
and an existing Comment
at the same time
My code
in my comment edit.ctp
file I did
<?= $this->Form->create($post); ?>
<?= $this->Form->input('title'); ?>
<?= $this->Form->input('title'); ?>
<?= $this->Form->input('text'); ?>
<?= $this->Form->input('comments.0.id'); ?>
<?= $this->Form->input('comments.0.text'); ?>
and in my PostsController
$post= $this->Posts->get($id);
$post= $this->Posts->patchEntity($post, $this->request->data, ['associated' => ['Comments']]);
My problem
now I expect that the comment will be updated, instead cake adds a new comment every time.
What did I do
I tried to debug $this->request->data
and I got
[
'text' => 'This is a test',
'comments' => [
(int) 0 => [
'id' => '168',
'text' => 'Comment test',
]
]
]
but if I debug $post
I get
object(App\Model\Entity\Post) {
/* ... */
'comments' => [
(int) 0 => object(App\Model\Entity\Comment) {
'text' => 'Comment test',
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'text' => true
],
/* ... */
}
],
/* ... */
'[dirty]' => [
'comments' => true,
],
}
So why comment is marked as 'new' when I pass its id
to the controller?
Of course this is an over simplified version of my actual situation. Maybe the problem it's not in the above code and i have to look elsewhere in my other code.
My question here is if I'm doing some basic approach error.
You need to read the associated data into your entity in order to be able to patch it, otherwise the data won't be merged, but just marshalled, and thus ends up being handled as "new".
Automatically loading associated data only happens for the special
_ids
key, and when there is at least one entry in the association property, ie actually you don't need to have the associated data loaded that you want to patch, but there must be something in order for the marshaller to reach the point where data is being read and merged.To be exact, without any data in the
comments
property, the marshaller will step out herehttps://github.com/cakephp/cakephp/blob/3.2.8/src/ORM/Marshaller.php#L653-L655
I can't really tell whether there might be a bug, at the very least I guess the docs would need to be updated around this, as they would be a little misleading. While they do try to explain what happens when associated data is missing in the source entity, the shown example currently doesn't work, and they say that new entities would only be created for
belongsTo
andhasOne
associations, which is incorrect.Cookbook > Database Access & ORM > Saving Data > Patching HasMany and BelongsToMany
You may want to file an issue over at GitHub for clarification.
tl;dr
Long story short, contain the comments and you should be good.