Saving associated hasOne - not working ):

Hello!

I am trying to save an associated model (defined in Table) through the patchEntity method.

Table Channel

PK - ChannelId
Name .. 
...
...

Table ChannelContact

PK/FK - ChannelId
Street ....
Place ....

ChannelTable.php

 $this->hasOne('ChannelContact', [
           'foreignKey' => 'ChannelId',
           'propertyName' => 'Contact',
            'dependent' => true
        ]);

ChannelContactTable.php

$this->belongsTo('Channel', [
            'foreignKey' => 'ChannelId',
            'propertyName' => 'Channel'
        ]);

ChannelController.php add()

public function add()
    {
        $users = $this->User->find('list')->select(['UserId', 'Username'])->toArray();

        $countries = TableRegistry::get('Country')->find('list')->select(['CountryId', 'Name'])->toArray();

        $channel = $this->Channel->newEntity();

        $channel->PasswordDisplay = $this->UserUtil->generatePassword(24);

        if ($this->request->is('post')) {

            $channel = $this->Channel->patchEntity($channel, $this->request->data, ['associated' => ['ChannelContact']]);

            $channel->Password = $channel->PasswordDisplay;

            $timestamp = Time::now();
            $channel->DateCreate = $channel->DateChange = $timestamp;
            $channel->Deleted = 0;

            if ($this->Channel->save($channel, ['associated' => ['ChannelContact']])) {
                $this->Flash->success(__('Der Channel wurde gespeichert!'));

                debug($channel);


                //return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('Der Channel konnte nicht gespeichert werden. Versuchen Sie es später erneut!'));
        }

        $this->set('users', $users);
        $this->set('countries', $countries);

        $this->set(compact(['channel', 'channelContact']));
        $this->set('_serialize', ['channel']);
    }

Output of add()-debug:

object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'twuGX5eClL0gWjPJ3RAi4g0y',
	'UserId' => (int) 1,
	'Description' => 'asdas',
	'Mode' => 'stream',
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'Street' => 'abc',
		'ZipCode' => '1234',
		'Place' => 'Ort',
		'CountryId' => '1',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '',
		'PhoneTwo' => '',
		'EmailOne' => '',
		'EmailTwo' => ''
	],
	'Password' => '$2y$10$eviwYiUUTc4Dc4niO4jI3uaij0Y5LRCbB.pLCCd/GtK0kmf3y1AmC',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-20T12:33:35+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-20T12:33:35+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'ChannelId' => (int) 18,
	'[new]' => false,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [],
	'[original]' => [],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

Every post on “add” results in an new row in channel table, but not one in child table “channel_contact”.

UPDATE:

while waiting for response on this topic i tried to implement an “hasMany” - “1 to n” association -> wasted (also not working for me?)

1 channel has n channel_opening_hour

Table channel_opening_hour

ChannelOpeningHourId (PK)
ChannelId (FK)
Day
...

ChannelOpeningHourTable.php

$this->belongsTo('Channel', [
            'foreignKey' => 'ChannelId',
            'propertyName' => 'Channel'
        ]);

ChannelTable.php

$this->hasMany('ChannelOpeningHour', [
            'foreignKey' => 'ChannelId',
            'propertyName' => 'OpeningHour',
            'dependent' => true
        ]);

ChannelContact is not converted into entity object. Can you share your $this->request->data content. So it would be easier to understand the problem.

Hello sohelrana820!

Thanks for your response. I did not found any conversion to an entity object in the cakebook, did I miss something?

Request data:

object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'a5DmdlBK7CYD2sSi3QiGRFax',
	'UserId' => (int) 1,
	'Description' => 'asdasd',
	'Mode' => 'stream',
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'ChannelId' => '',
		'Street' => 'An der Goldenen Stiege 14/1',
		'ZipCode' => '2340',
		'Place' => '',
		'CountryId' => '156',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '',
		'PhoneTwo' => '',
		'EmailOne' => '',
		'EmailTwo' => ''
	],
	'ChannelSupport' => [
		'ChannelId' => '',
		'HardwareModel' => '',
		'Distributor' => '',
		'Manufacturer' => '',
		'SerialNr' => '',
		'MacLan' => '',
		'MacWlan' => '',
		'Hostname' => '',
		'IP' => '',
		'Subnet' => '',
		'Gateway' => '',
		'DNS' => '',
		'WarrantyThru' => '',
		'DateInstall' => '',
		'DateShip' => '',
		'SetupBy' => '',
		'AmplifierModel' => '',
		'AmplifierManufacturer' => '',
		'AmplifierWarranyThru' => '',
		'SpeakerCount' => '',
		'ServiceProvider' => '',
		'InternetProvider' => '',
		'Remarks' => ''
	],
	'ChannelOpeningHour' => [
		(int) 0 => [
			'Day' => 'Montag',
			'OpenTime' => '00:00',
			'CloseTime' => '02:00'
		]
	],
	'Password' => '$2y$10$ZbsPlfGnUDUj5A2q73sGgO5cfWc2i8bOn7gPYhennfXM1U0xsJ59a',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-21T08:53:15+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-21T08:53:15+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'ChannelId' => (int) 23,
	'[new]' => false,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [],
	'[original]' => [],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

is there no one with any idea? :confused:

I tried to replicate your issue but working fine on my machine. Have you properly associated the Table names in patchEntity?

Hi avvrug, thanks for your response!

I did it this way:

$channel = $this->Channel->patchEntity($channel, $this->request->data, ['associated' => ['ChannelContact', 'ChannelOpeningHour', 'ChannelSupport']]);

This is the correct way, try to debug it after patchEntity.

i will give output shortly …

after patching:

\src\Controller\ChannelController.php (line 93)
object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'Ymkj6DnTj6lJ92EXKloGP3e5',
	'UserId' => (int) 1,
	'Description' => 'test',
	'Mode' => 'stream',
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'ChannelId' => '',
		'Street' => 'An der Goldenen Stiege 123',
		'ZipCode' => '2340',
		'Place' => '',
		'CountryId' => '156',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '',
		'PhoneTwo' => '',
		'EmailOne' => '',
		'EmailTwo' => ''
	],
	'ChannelSupport' => [
		'ChannelId' => '',
		'HardwareModel' => '',
		'Distributor' => '',
		'Manufacturer' => '',
		'SerialNr' => '',
		'MacLan' => '',
		'MacWlan' => '',
		'Hostname' => '',
		'IP' => '',
		'Subnet' => '',
		'Gateway' => '',
		'DNS' => '',
		'WarrantyThru' => '',
		'DateInstall' => '',
		'DateShip' => '',
		'SetupBy' => '',
		'AmplifierModel' => '',
		'AmplifierManufacturer' => '',
		'AmplifierWarranyThru' => '',
		'SpeakerCount' => '',
		'ServiceProvider' => '',
		'InternetProvider' => '',
		'Remarks' => ''
	],
	'ChannelOpeningHour' => [
		(int) 0 => [
			'Day' => 'Montag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 1 => [
			'Day' => 'Dienstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 2 => [
			'Day' => 'Mittwoch',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 3 => [
			'Day' => 'Donnerstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 4 => [
			'Day' => 'Freitag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 5 => [
			'Day' => 'Samstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 6 => [
			'Day' => 'Sonntag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		]
	],
	'Password' => '$2y$10$963IfZqpC1x4pUmuHCrAtuGzLCQt30hWU4aYSOgr6D7XPRHVQNWyi',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:05:52+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:05:52+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'[new]' => true,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [
		'PasswordDisplay' => true,
		'UserId' => true,
		'Description' => true,
		'Mode' => true,
		'FSK' => true,
		'Active' => true,
		'ChannelContact' => true,
		'ChannelSupport' => true,
		'ChannelOpeningHour' => true,
		'Password' => true,
		'DateChange' => true,
		'DateCreate' => true,
		'Deleted' => true
	],
	'[original]' => [
		'PasswordDisplay' => 'Q8TBeSdoTlNnl9ELammLDsKS'
	],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

after saving:

\src\Controller\ChannelController.php (line 100)
object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'Ymkj6DnTj6lJ92EXKloGP3e5',
	'UserId' => (int) 1,
	'Description' => 'test',
	'Mode' => 'stream',
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'ChannelId' => '',
		'Street' => 'An der Goldenen Stiege 123',
		'ZipCode' => '2340',
		'Place' => '',
		'CountryId' => '156',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '',
		'PhoneTwo' => '',
		'EmailOne' => '',
		'EmailTwo' => ''
	],
	'ChannelSupport' => [
		'ChannelId' => '',
		'HardwareModel' => '',
		'Distributor' => '',
		'Manufacturer' => '',
		'SerialNr' => '',
		'MacLan' => '',
		'MacWlan' => '',
		'Hostname' => '',
		'IP' => '',
		'Subnet' => '',
		'Gateway' => '',
		'DNS' => '',
		'WarrantyThru' => '',
		'DateInstall' => '',
		'DateShip' => '',
		'SetupBy' => '',
		'AmplifierModel' => '',
		'AmplifierManufacturer' => '',
		'AmplifierWarranyThru' => '',
		'SpeakerCount' => '',
		'ServiceProvider' => '',
		'InternetProvider' => '',
		'Remarks' => ''
	],
	'ChannelOpeningHour' => [
		(int) 0 => [
			'Day' => 'Montag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 1 => [
			'Day' => 'Dienstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 2 => [
			'Day' => 'Mittwoch',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 3 => [
			'Day' => 'Donnerstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 4 => [
			'Day' => 'Freitag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 5 => [
			'Day' => 'Samstag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		],
		(int) 6 => [
			'Day' => 'Sonntag',
			'OpenTime' => '00:30',
			'CloseTime' => '00:30'
		]
	],
	'Password' => '$2y$10$963IfZqpC1x4pUmuHCrAtuGzLCQt30hWU4aYSOgr6D7XPRHVQNWyi',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:05:52+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:05:52+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'ChannelId' => (int) 25,
	'[new]' => false,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [],
	'[original]' => [],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

ChannelId is primary key no need to set that please remove it from your form and this should work. Also If that will empty how this suppose to save?

I just added “ChannelId” as form field to check if would work with that, because without it did not work either.

Output without PK field in form (after patchEntity):

\src\Controller\ChannelController.php (line 93)
object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'mpvm4tAJV7EWNsYwajF7hDmf',
	'UserId' => (int) 4,
	'Description' => 'Test',
	'Mode' => 'stream',
	'OfflineDuration' => (int) -2,
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'Street' => 'An der Goldenen Stiege 14/4',
		'ZipCode' => '2340',
		'Place' => 'Mödling',
		'CountryId' => '156',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '06603745576',
		'PhoneTwo' => '06603745576',
		'EmailOne' => 'andre.karner@gmail.com',
		'EmailTwo' => 'andre.karner@gmail.com'
	],
	'ChannelSupport' => [
		'HardwareModel' => '',
		'Distributor' => '',
		'Manufacturer' => '',
		'SerialNr' => '',
		'MacLan' => '',
		'MacWlan' => '',
		'Hostname' => '',
		'IP' => '',
		'Subnet' => '',
		'Gateway' => '',
		'DNS' => '',
		'WarrantyThru' => '',
		'DateInstall' => '',
		'DateShip' => '',
		'SetupBy' => '',
		'AmplifierModel' => '',
		'AmplifierManufacturer' => '',
		'AmplifierWarranyThru' => '',
		'SpeakerCount' => '',
		'ServiceProvider' => '',
		'InternetProvider' => '',
		'Remarks' => ''
	],
	'ChannelOpeningHour' => [
		(int) 0 => [
			'Day' => 'Montag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 1 => [
			'Day' => 'Dienstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 2 => [
			'Day' => 'Mittwoch',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 3 => [
			'Day' => 'Donnerstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 4 => [
			'Day' => 'Freitag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 5 => [
			'Day' => 'Samstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 6 => [
			'Day' => 'Sonntag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		]
	],
	'Password' => '$2y$10$NvfY9yWVLioIogkQvtCx6OjoNFTBxY.WiCs1PHqiFrWza/K21pn7e',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:14:46+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:14:46+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'[new]' => true,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [
		'PasswordDisplay' => true,
		'UserId' => true,
		'Description' => true,
		'Mode' => true,
		'OfflineDuration' => true,
		'FSK' => true,
		'Active' => true,
		'ChannelContact' => true,
		'ChannelSupport' => true,
		'ChannelOpeningHour' => true,
		'Password' => true,
		'DateChange' => true,
		'DateCreate' => true,
		'Deleted' => true
	],
	'[original]' => [
		'PasswordDisplay' => 'GmDMiUe1s8xgRnyIbQ7SEjpl'
	],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

after save:

\src\Controller\ChannelController.php (line 100)
object(App\Model\Entity\Channel) {

	'PasswordDisplay' => 'mpvm4tAJV7EWNsYwajF7hDmf',
	'UserId' => (int) 4,
	'Description' => 'Test',
	'Mode' => 'stream',
	'OfflineDuration' => (int) -2,
	'FSK' => true,
	'Active' => true,
	'ChannelContact' => [
		'Street' => 'An der Goldenen Stiege 14/4',
		'ZipCode' => '2340',
		'Place' => 'Mödling',
		'CountryId' => '156',
		'ContactPersonOne' => '',
		'ContactPersonTwo' => '',
		'ContactPersonPositionOne' => '',
		'ContactPersonPositionTwo' => '',
		'PhoneOne' => '06603745576',
		'PhoneTwo' => '06603745576',
		'EmailOne' => 'andre.karner@gmail.com',
		'EmailTwo' => 'andre.karner@gmail.com'
	],
	'ChannelSupport' => [
		'HardwareModel' => '',
		'Distributor' => '',
		'Manufacturer' => '',
		'SerialNr' => '',
		'MacLan' => '',
		'MacWlan' => '',
		'Hostname' => '',
		'IP' => '',
		'Subnet' => '',
		'Gateway' => '',
		'DNS' => '',
		'WarrantyThru' => '',
		'DateInstall' => '',
		'DateShip' => '',
		'SetupBy' => '',
		'AmplifierModel' => '',
		'AmplifierManufacturer' => '',
		'AmplifierWarranyThru' => '',
		'SpeakerCount' => '',
		'ServiceProvider' => '',
		'InternetProvider' => '',
		'Remarks' => ''
	],
	'ChannelOpeningHour' => [
		(int) 0 => [
			'Day' => 'Montag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 1 => [
			'Day' => 'Dienstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 2 => [
			'Day' => 'Mittwoch',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 3 => [
			'Day' => 'Donnerstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 4 => [
			'Day' => 'Freitag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 5 => [
			'Day' => 'Samstag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		],
		(int) 6 => [
			'Day' => 'Sonntag',
			'OpenTime' => '00:00',
			'CloseTime' => '00:00'
		]
	],
	'Password' => '$2y$10$NvfY9yWVLioIogkQvtCx6OjoNFTBxY.WiCs1PHqiFrWza/K21pn7e',
	'DateChange' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:14:46+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'DateCreate' => object(Cake\I18n\Time) {

		'time' => '2017-02-23T12:14:46+00:00',
		'timezone' => 'UTC',
		'fixedNowTime' => false
	
	},
	'Deleted' => (int) 0,
	'ChannelId' => (int) 26,
	'[new]' => false,
	'[accessible]' => [
		'*' => true
	],
	'[dirty]' => [],
	'[original]' => [],
	'[virtual]' => [],
	'[errors]' => [],
	'[invalid]' => [],
	'[repository]' => 'Channel'

}

still no "sub-"entries in database :cry:

This seems the edit form because ChannelId is still there not in the associated data but in the Channel repository.

nope it isnt. i uploaded the add.ctp on pastebin: http://pastebin.com/L14ujy5S

The ChannelId just get visible after calling the save() method - in the first output (after patchEntity) the field ‘ChannelId’ is not present in the output.

I am really running out of ideas … that was the reason why I started a topic in this forums :slight_smile:

I found something new, while going deep in the core …

The reason why my associations are not getting saved is, because the output of the first expression is true (for every associated model). Therefore the “save” method is not called. Now I have to find out, why this expression is getting true.

if ($relation->isOwningSide($table) !== $owningSide) {
                continue;
            }
if (!$this->_save($relation, $entity, $nested, $options)) {
      return false;
}

AssociationCollection.php ln: 241

UPDATE: will, i give up - I hope that somebody may give me further assistance.

No, if the issue you are facing there must be something wrong either on your side or maybe something that I am missing. Let me see once more and also could you please follow the CakePHP conventions maybe because you are not following the conventions the issue is happening.

well, i designed the database first, before i was deciding to use CakePHP - therefore my column names are not convenient as CakePHP describes …

Ok, But can you update the database structure as per CakePHP conventions. That will be also helpful in debugging the issue.

well … I see. Would you post me the example you reproduced?

Tabledefinition
CakePHP Tabledefinition
Controller method (add)
add.ctp Template

I just tried with bake and it was not supported because of the table names the table names should like small case and pluralize. Just like that there may be something behind the conflicts which is stopping to save the associated data.

well, I see … so Table “Channel” would be “channels”- do I also have to alter my column names? It would be a big mess, because my data-model is about ~40 tables. :confounded: