Discussion:
Cakephp 3.x patchEntity set "'new' => true" to entity in edit function
Paulo Terra
2016-04-17 22:14:03 UTC
Permalink
Hi,
I am creating a user edit form consisting of five related entities as
follows:

Buyers belongsTo Users
Genres belongsToMany Buyers
Buyers belongsToMany Genres
Users hasOne Buyers
Users hasMany Addresses
Addresses belongsTo Users
Addresses belongsTo Countries
Countries hasMany Addresses

I create Buyers entity and sending the data to the view as follows:

$Buyer = $this->Buyers-> get($id ['contain' => ['Users', 'Users.Addresses',
'Users.Addresses.Countries', 'Genres']]);


Then send to the edit.ctp:

$Countries = $this->Buyers->Users->Addresses->Countries-> find('list');

$Genres = $this->Buyers->Genres->find('list' ['order' => ['description_pt'
=> 'ASC']]);

$This->set(compact ('buyer', 'countries', 'genres'));

$This->set( '_serialize'['buyer', 'countries', 'genres']);


The form data is correctly presented, which shows that the cake recognized
all fields as are in the database and they are filled with the correct data.

When sending the data they appear so (using debug):


object(App\Model\Entity\Buyer) {

'new' => false,
'accessible' => [
'cpf' => true,
'gender' => true,
'birthdate' => true,
'newsletter' => true,
'user_id' => true,
'user' => true,
'genres' => true
],
'properties' => [
'id' => (int) 68,
'cpf' => '01847348785',
'gender' => 'Masculino',
'birthdate' => object(Cake\I18n\Time) {

'time' => '1971-03-23T00:00:00+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'newsletter' => 'Sim',
'user_id' => (int) 164,
'genres' => [
(int) 0 => object(App\Model\Entity\Genre) {

'new' => false,
'accessible' => [
'description_pt' => true,
'description_en' => true,
'description_es' => true,
'buyers' => true,
'records' => true
],
'properties' => [
'id' => (int) 3,
'description_pt' => 'Bossa-Nova',
'description_en' => 'Bossa-Nova',
'description_es' => 'Bossa-Nova',
'_joinData' => object(App\Model\Entity\BuyersGenre) {

'new' => false,
'accessible' => [
'genre_id' => true,
'buyer_id' => true,
'genre' => true,
'buyer' => true
],
'properties' => [
'genre_id' => (int) 3,
'id' => (int) 66,
'buyer_id' => (int) 68
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'BuyersGenres'

}
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Genres'

}
],
'user' => object(App\Model\Entity\User) {

'new' => false,
'accessible' => [
'name' => true,
'password' => true,
'username' => true,
'status' => true,
'session' => true,
'ip' => true,
'role' => true,
'login_error' => true,
'survey_id' => true,
'survey' => true,
'other' => true,
'addresses' => true,
'buyers' => true,
'carts' => true,
'classifieds' => true,
'last_visited_ids' => true,
'orders' => true,
'refer_friends' => true,
'searches' => true,
'sellers' => true
],
'properties' => [
'id' => (int) 164,
'name' => 'Paulo Terra Matias',
'password' =>
'$2y$10$JKRUBVNjOon9amTnvKvrDeU4D/ZhVvYpKUDv9op1lC4eRIcP4es8G',
'username' => '***@gmail.com',
'created' => object(Cake\I18n\Time) {

'time' => '2016-04-09T21:07:28+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'modified' => object(Cake\I18n\Time) {

'time' => '2016-04-17T21:26:16+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'status' => 'Ativo',
'session' => 'd0a500904fd63a39ccb6d7556210ecfb',
'ip' => '201.53.143.193',
'role' => 'Comprador',
'login_error' => (int) 0,
'survey_id' => (int) 6,
'other' => 'sadasdsa',
'addresses' => [
(int) 0 => object(App\Model\Entity\Address) {

'new' => false,
'accessible' => [
'user_id' => true,
'country_id' => true,
'code' => true,
'type' => true,
'zipcode' => true,
'line1' => true,
'line2' => true,
'city' => true,
'state' => true,
'country' => true,
'phone' => true,
'celphone' => true,
'user' => true
],
'properties' => [
'id' => (int) 29,
'user_id' => (int) 164,
'code' => (int) 1,
'type' => 'Principal',
'zipcode' => '22222222',
'line1' => 'kjhkj',
'line2' => 'jhk',
'city' => 'jhkjhkj',
'state' => 'hj',
'country_id' => (int) 81,
'phone' => '',
'celphone' => '',
'country' => object(App\Model\Entity\Country) {

'new' => false,
'accessible' => [
'country_name' => true,
'addresses' => true
],
'properties' => [
'id' => (int) 81,
'country_name' => 'Haiti'
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Countries'

}
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Addresses'

}
]
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Users'

}
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Buyers'

}




The data that comes from the form after the post:


[
'user' => [
'name' => 'Paulo Terra Matias',
'username' => '***@gmail.com',
'addresses' => [
(int) 0 => [
'phone' => '999999999',
'celphone' => '',
'zipcode' => '22222222',
'line1' => 'kjhkj',
'line2' => 'jhk',
'city' => 'jhkjhkj',
'state' => 'hj',
'country_id' => '81'
]
]
],
'cpf' => '01847348785',
'gender' => 'Masculino',
'birthdate' => [
'year' => '1971',
'month' => '03',
'day' => '23'
],
'genres' => [
'_ids' => [
(int) 0 => '3'
]
],
'newsletter' => 'Sim'
]
==========================================

However, after patchEntity the entity Address is marked as 'new' => true,

This makes the cake try to create a new Address record, when in fact, I
want to edit the current Address record.

What am I doing wrong?



$ Buyer = $ this-> Buyers-> patchEntity ($ buyer, $ this-> request-> data [
'Associated' => [
'Users',
'Users.Addresses'
'Users.Addresses.Countries'
'Genres'
]
]);


object(App\Model\Entity\Buyer) {

'new' => false,
'accessible' => [
'cpf' => true,
'gender' => true,
'birthdate' => true,
'newsletter' => true,
'user_id' => true,
'user' => true,
'genres' => true
],
'properties' => [
'id' => (int) 68,
'cpf' => '01847348785',
'gender' => 'Masculino',
'birthdate' => object(Cake\I18n\Time) {

'time' => '1971-03-23T00:00:00+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'newsletter' => 'Sim',
'user_id' => (int) 164,
'genres' => [
(int) 0 => object(App\Model\Entity\Genre) {

'new' => false,
'accessible' => [
'description_pt' => true,
'description_en' => true,
'description_es' => true,
'buyers' => true,
'records' => true
],
'properties' => [
'id' => (int) 3,
'description_pt' => 'Bossa-Nova',
'description_en' => 'Bossa-Nova',
'description_es' => 'Bossa-Nova'
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Genres'

}
],
'user' => object(App\Model\Entity\User) {

'new' => false,
'accessible' => [
'name' => true,
'password' => true,
'username' => true,
'status' => true,
'session' => true,
'ip' => true,
'role' => true,
'login_error' => true,
'survey_id' => true,
'survey' => true,
'other' => true,
'addresses' => true,
'buyers' => true,
'carts' => true,
'classifieds' => true,
'last_visited_ids' => true,
'orders' => true,
'refer_friends' => true,
'searches' => true,
'sellers' => true
],
'properties' => [
'id' => (int) 164,
'name' => 'Paulo Terra Matias',
'password' => '$2y$10$JKRUBVNjOon9amTnvKvrDeU4D/ZhVvYpKUDv9op1lC4eRIcP4es8G',
'username' => '***@gmail.com',
'created' => object(Cake\I18n\Time) {

'time' => '2016-04-09T21:07:28+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'modified' => object(Cake\I18n\Time) {

'time' => '2016-04-17T21:26:16+0000',
'timezone' => 'UTC',
'fixedNowTime' => false

},
'status' => 'Ativo',
'session' => 'd0a500904fd63a39ccb6d7556210ecfb',
'ip' => '201.53.143.193',
'role' => 'Comprador',
'login_error' => (int) 0,
'survey_id' => (int) 6,
'other' => 'sadasdsa',
'addresses' => [
(int) 0 => object(App\Model\Entity\Address) {

'new' => true,
'accessible' => [
'user_id' => true,
'country_id' => true,
'code' => true,
'type' => true,
'zipcode' => true,
'line1' => true,
'line2' => true,
'city' => true,
'state' => true,
'country' => true,
'phone' => true,
'celphone' => true,
'user' => true
],
'properties' => [
'phone' => '999999999',
'celphone' => '',
'zipcode' => '22222222',
'line1' => 'kjhkj',
'line2' => 'jhk',
'city' => 'jhkjhkj',
'state' => 'hj',
'country_id' => (int) 81
],
'dirty' => [
'phone' => true,
'celphone' => true,
'zipcode' => true,
'line1' => true,
'line2' => true,
'city' => true,
'state' => true,
'country_id' => true
],
'original' => [],
'virtual' => [],
'errors' => [
'code' => [
'_required' => 'This field is required'
],
'type' => [
'_required' => 'This field is required'
]
],
'repository' => 'Addresses'

}
]
],
'dirty' => [
'addresses' => true
],
'original' => [
'addresses' => [
(int) 0 => object(App\Model\Entity\Address) {

'new' => false,
'accessible' => [
'user_id' => true,
'country_id' => true,
'code' => true,
'type' => true,
'zipcode' => true,
'line1' => true,
'line2' => true,
'city' => true,
'state' => true,
'country' => true,
'phone' => true,
'celphone' => true,
'user' => true
],
'properties' => [
'id' => (int) 29,
'user_id' => (int) 164,
'code' => (int) 1,
'type' => 'Principal',
'zipcode' => '22222222',
'line1' => 'kjhkj',
'line2' => 'jhk',
'city' => 'jhkjhkj',
'state' => 'hj',
'country_id' => (int) 81,
'phone' => '',
'celphone' => '',
'country' => object(App\Model\Entity\Country) {

'new' => false,
'accessible' => [
'country_name' => true,
'addresses' => true
],
'properties' => [
'id' => (int) 81,
'country_name' => 'Haiti'
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Countries'

}
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Addresses'

}
]
],
'virtual' => [],
'errors' => [],
'repository' => 'Users'

}
],
'dirty' => [
'user' => true,
'genres' => true
],
'original' => [
'genres' => [
(int) 0 => object(App\Model\Entity\Genre) {

'new' => false,
'accessible' => [
'description_pt' => true,
'description_en' => true,
'description_es' => true,
'buyers' => true,
'records' => true
],
'properties' => [
'id' => (int) 3,
'description_pt' => 'Bossa-Nova',
'description_en' => 'Bossa-Nova',
'description_es' => 'Bossa-Nova',
'_joinData' => object(App\Model\Entity\BuyersGenre) {

'new' => false,
'accessible' => [
'genre_id' => true,
'buyer_id' => true,
'genre' => true,
'buyer' => true
],
'properties' => [
'genre_id' => (int) 3,
'id' => (int) 66,
'buyer_id' => (int) 68
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'BuyersGenres'

}
],
'dirty' => [],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Genres'

}
]
],
'virtual' => [],
'errors' => [],
'repository' => 'Buyers'

}
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
heavyKevy
2016-04-18 07:50:17 UTC
Permalink
First off you don't need to cotain users 3 times, Users.Addresses.Countries includes all 3 tables already.

Secondly, if the address has the id, it should automatically detect that it is being edited, if the id is missing it will add the address.
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Paulo Terra
2016-04-19 16:41:53 UTC
Permalink
Hi heavyKevy, thank you for your answer!

Ok, about your first advise, I simplified and its ok, but about the issue,
thatÂŽs it, the problem is the missind ID. But I simlpy donÂŽt know why all
other entitys comes with the id and Addresses not! That is the problem. Do
you know why?

Thanks in advance!

Paulo Terra
Post by heavyKevy
First off you don't need to cotain users 3 times,
Users.Addresses.Countries includes all 3 tables already.
Secondly, if the address has the id, it should automatically detect that
it is being edited, if the id is missing it will add the address.
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
heavyKevy
2016-04-20 04:11:36 UTC
Permalink
Does your edit form have an input for the address_id?

something like:"user.addresses.0.id"

I see the id: (29) for the address in the debug output of the entity...

If you need further help with it, you are going to need to show the edit form in order to figure out what may be missing.

Hope that helps...
Best regards,
Kevin
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Paulo Terra
2016-04-20 12:48:45 UTC
Permalink
Hi Kekin, it is very kind of you help this poor Cake novice. It have been
hard programing days.

Ok, if I have a hidden ID field of the Addresses I think it is going to
work. But why do I have to put the Addresses ID and the other entities work
without it?

Here is the form:

PS: Thanks again for your patience


<?
echo $this->Form->create($buyer);
?>

<div class="col-md-8 col-sm-8 col-xm-8 col-centered">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><?= __('Atualizar dados de cadastro')
?></h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8"><?=
$this->Form->input('user.name',['label' => __('Nome')]);?></div>
<div class="col-md-4"><?= $this->Form->input('cpf',['label'
=> __('CPF')]);?></div>
</div>
<div class="row">
<div class="col-md-4"><?=
$this->Form->input('user.username',['label' => __('Email')]);?></div>
</div>

<div class="row">
<div class="col-md-2">
<?= $this->Form->label(__('Sexo'));?>
</div>
<? $options = array('Masculino' => __('Masculino'),
'Feminino' => __('Feminino'));?>
<div class="col-md-2">
<?= $this->Form->radio('gender', $options);?>
</div>
<div class="col-md-6">
<?= $this->Form->label('birthdate',__('Data de
nascimento'));?>
<?= $this->Form->input(
'birthdate',
array (
'label' =>
false,
'minYear' =>
date('Y') - 100,
'maxYear' =>
date('Y') - 12,
'empty' =>
true,
'monthNames' => true,
'default' => ''
)
);

?>
</div>
</div>

<div class="row">
<div class="col-md-4">
<?=
$this->Form->input('user.addresses.0.phone',['label' => __('Telefone')]);?>
</div>
<div class="col-md-4">
<?=
$this->Form->input('user.addresses.0.celphone',['label' =>
__('Celular')]);?>
</div>
</div>
<div class="row">
<div class="col-md-4">
<?=
$this->Form->input('user.addresses.0.zipcode',['label' => __('CEP')]);?>
</div>
</div>
<div class="row">
<div class="col-md-12">
<?=
$this->Form->input('user.addresses.0.line1',['label' => __('Endereço e
número')]);?>
</div>
</div>
<div class="row">
<div class="col-md-12">
<?=
$this->Form->input('user.addresses.0.line2',['label' => __('Complemento e
Bairro')]);?>
</div>
</div>
<div class="row">
<div class="col-md-5">
<?= $this->Form->input('user.addresses.0.city',['label'
=> __('Cidade')]);?>
</div>
<div class="col-md-3">
<?=
$this->Form->input('user.addresses.0.state',['label' => __('Estado')]);?>
</div>
<div class="col-md-4">
<?=
$this->Form->input('user.addresses.0.country_id',['options' =>
$countries,'label' => __('País')]);?>

</div>
</div>
<div class="row">
<div class="col-md-12">

<?php
echo $this->Form->label(__('Preferências musicais'));
echo $this->Form->input('genres._ids',
[
'templates' => ['checkboxWrapper' => '<div
class="col-md-3"><div class="checkbox">{{label}}</div></div>'],
'options' => $genres,
'multiple' => 'checkbox',
'label' => false,
//'value' => $buyer
]);
?>
</div>
</div>
<div class="row">
<div class="col-md-12">
&nbsp;
</div>
</div>
<div class="row">
<div class="col-md-6">
<?= $this->Form->label(__('Receber novidades'));?>
<?= $this->Form->input('newsletter',['type' =>
'checkbox','value' => 'Sim','hiddenField'=>'Não', 'label' => __('Quero
receber email de novidades do Prefiro Vinil')]);?>
</div>
</div>
<?
//hidden fields
?>
<div class="row">
<div class="col-md-1">
<div class="control-group">
<?= $this->Form->button(__('Salvar'), ['class' =>
'btn-success']) ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->Form->end() ?>
Post by heavyKevy
Does your edit form have an input for the address_id?
something like:"user.addresses.0.id"
I see the id: (29) for the address in the debug output of the entity...
If you need further help with it, you are going to need to show the edit
form in order to figure out what may be missing.
Hope that helps...
Best regards,
Kevin
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
heavyKevy
2016-04-20 14:59:41 UTC
Permalink
I am not sure why the others appear to be working, I suggest that you test thoroughly to make sure they are doing as expected.
It may be because of the many - to -one relationship though.

Let me know how it goes.
Regards,
Kevin
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Paulo Terra
2016-04-25 21:27:44 UTC
Permalink
Hi Kevin,

It worked perfectly!!

I just would lime to know why only Addresses need the id.

But if you dont know, thats OK. You already relped me!!

Thanks a lot!

Best regards,

Paulo Terra
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
heavyKevy
2016-04-26 04:41:05 UTC
Permalink
Thanks for the update, I am glad to hear that it is working for you.

It seems to me that in order for the system to know which record is being updated, that all of the ids should need to be supplied for every record that is being saved in a transaction. If it is saving a record for which you did not supply an id, then it must be able to figure out the id via the relationship but can't do that with addresses when there can be multiple addresses that are related.

Best regards,
Kevin
--
Sign up for our Newsletter for updates.
http://cakephp.org/newsletter/signup

We will soon be closing this Google Group. But don't worry, we have something better coming. Stay tuned for an updated from the CakePHP Team soon.

Like Us on FaceBook https://www.facebook.com/CakePHP
Follow us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...