So I have 2 models: Plugins and Imports. The association is Plugins hasOne Imports:
$this->hasOne('Imports', [
'foreignKey' => 'plugin_id'
]);
and Imports belongsTo Plugins:
$this->belongsTo('Plugins', [
'foreignKey' => 'plugin_id',
'joinType' => 'INNER'
]);
My plugins-table dump looks like this:
CREATE TABLE `plugins` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`type` varchar(50) NOT NULL,
`pluginkey` varchar(100) NOT NULL,
`pluginname` varchar(255) DEFAULT NULL,
`description` text,
`integrationinstructions` text,
`date_available` datetime DEFAULT NULL,
`date_last_changed` datetime DEFAULT NULL,
`author` varchar(255) DEFAULT NULL,
`version` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
and my imports table is:
CREATE TABLE imports (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
plugintype VARCHAR(50) NOT NULL,
importedpluginkey VARCHAR(255) NOT NULL,
imported DATETIME NULL DEFAULT NULL,
plugin_id INT UNSIGNED NOT NULL,
FOREIGN KEY plugin_key (plugin_id) REFERENCES plugins(id)
);
Now i baked both controllers and everything works fine. I can save an import(will later be used to import xml files) and it is linked to a plugin.
But now I want to let the Plugindata update through data I add in an import.
For example let's say i have a Plugin called "sale" with the type Wordpress and the key "wp_sale". Now i want to update this plugin by adding an import. For example changing it's description or name.
If i understand this right, I would only need to pass the data I want to change in the plugins alongside the id.
But when I check the patchEntity that is going to be safed the Plugin Entity is always '[new]'=> true, and the id I passed is gone.
This is what my controller looks like:
public function add()
{
$import = $this->Imports->newEntity();
if ($this->request->is('post')) {
$import = $this->Imports->patchEntity($import, $this->request->data, ['associated' => ['Plugins']]);
if ($this->Imports->save($import)) {
$this->Flash->success(__('The import has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The import could not be saved. Please, try again.'));
}
}
$plugins = $this->Imports->Plugins->find('list', ['limit' => 200]);
$this->set(compact('import', 'plugins'));
$this->set('_serialize', ['import']);
}
And this is what my form looks like:
echo $this->Form->input('plugintype');
echo $this->Form->input('importedpluginkey');
echo $this->Form->input('imported');
echo $this->Form->input('plugin_id', ['options' => $plugins]);
echo $this->Form->input('plugin.pluginkey');
echo $this->Form->input('plugin.type');
echo $this->Form->input('plugin.id', ['value' => 1]);
I gave the plugin.id the value 1 just for the sake of testing, because I wanted to pass an id for the Plugin.
My postdata looks like this:
[
'plugintype' => 'wordpress',
'importedpluginkey' => 'wp_sale',
'imported' => [
'year' => '2015',
'month' => '11',
'day' => '24',
'hour' => '10',
'minute' => '38'
],
'plugin_id' => '1',
'plugin' => [
'pluginkey' => 'wp_sale',
'type' => 'wordpress',
'id' => '1'
]
]
And the patched Entity looks like this:
object(App\Model\Entity\Import) {
'plugintype' => 'wordpress',
'importedpluginkey' => 'wp_sale',
'imported' => object(Cake\I18n\Time) {
'time' => '2015-11-24T11:04:00+0000',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'plugin_id' => (int) 1,
'plugin' => object(App\Model\Entity\Plugin) {
'pluginkey' => 'wp_sale',
'type' => 'wordpress',
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'pluginkey' => true,
'type' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Plugins'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'plugintype' => true,
'importedpluginkey' => true,
'imported' => true,
'plugin_id' => true,
'plugin' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Imports'
}
Many Questions on this site are about association saving. But what i want is update associated data when adding new data in the import model.
The reasoning behind it is, that I want to be able to update my Plugins without editing everyone of them, and just use the xml import.
If the Question still is unclear feel free to ask and I will explain myself further. Thanks in advance!
Edit: To be clear, I basically need to change the data of a plugin using the import controller.
I now got the plugin entity in another function now, and i can save that with the import entity. However, it doesnt change anything in the plugin, so basically that does nothing.
The example in the linked docs seem to assume that the entities are set up in a way that they allow the primary key to be mass assigned, see
Cookbook > Database Access & ORM > Entities > Mass Assignment
By default, baked entities do not allow the primary key to be mass assigned, so you have to take care of that, for example by overriding the fields accessible state via the patchEntitity()
options, like
$import = $this->Imports->patchEntity(
$import,
$this->request->data,
[
'associated' => [
'Plugins' => [
'accessibleFields' => ['id' => true]
]
]
]
);
See also Cookbook > Database Access & ORM > Saving Data > Changing Accessible Fields
Note that while the entity will still be flagged as "new", the saving process will (as long as the checkExisting
option is not being set to false
) test whether a record with the given primary key exists, and in case necessary mark the entity as "non-new" before proceeding, so that you'll end up with an update instead of an insert.
See also Cookbook > Database Access & ORM > Saving Data > Saving Entities