Cakephp 3,更新关联的属于数据
Cakephp 3, Updating associated belongsto Data
所以我有 2 个模型:插件和导入。
关联是 Plugins hasOne Imports:
$this->hasOne('Imports', [
'foreignKey' => 'plugin_id'
]);
并导入属于插件:
$this->belongsTo('Plugins', [
'foreignKey' => 'plugin_id',
'joinType' => 'INNER'
]);
我的插件-table 转储如下所示:
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;
我的导入 table 是:
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)
);
现在我烤了两个控制器,一切正常。我可以保存一个导入(稍后将用于导入 xml 文件)并且它链接到一个插件。
但现在我想让 Plugindata 通过我在导入中添加的数据进行更新。
例如,假设我有一个名为 "sale" 的插件,类型为 Wordpress,键为 "wp_sale"。现在我想通过添加导入来更新这个插件。例如更改它的描述或名称。
如果我理解 this 正确,我只需要将我想在插件中更改的数据与 id 一起传递。
但是,当我检查将要保护的 patchEntity 时,插件实体始终为“[new]”=> true,我传递的 ID 消失了。
这是我的控制器的样子:
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']);
}
我的表格是这样的:
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]);
我给 plugin.id 值 1 只是为了测试,因为我想为插件传递一个 id。
我的帖子数据是这样的:
[
'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'
]
]
修补后的实体如下所示:
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'
}
此站点上的许多问题都与关联保存有关。但我想要的是在导入模型中添加新数据时更新关联数据。
其背后的原因是,我希望能够更新我的插件而无需编辑每个插件,只需使用 xml 导入。
如果问题仍然不清楚,请随时提问,我会进一步解释。提前致谢!
编辑:要清楚,我基本上需要使用导入控制器更改插件的数据。
我现在在另一个函数中得到了插件实体,我可以用导入实体保存它。但是,它不会更改插件中的任何内容,所以基本上什么都不做。
在这里加上dependent
,我想这样就可以了。
$this->hasOne('Imports', [
'foreignKey' => 'plugin_id',
'dependent' => true,
]);
链接文档中的示例似乎假设实体的设置方式允许批量分配主键,请参阅
Cookbook > Database Access & ORM > Entities > Mass Assignment
主键需要可访问
默认情况下,烘焙实体不允许批量分配主键,因此您必须注意这一点,例如通过 patchEntitity()
选项覆盖字段可访问状态,例如
$import = $this->Imports->patchEntity(
$import,
$this->request->data,
[
'associated' => [
'Plugins' => [
'accessibleFields' => ['id' => true]
]
]
]
);
另见 Cookbook > Database Access & ORM > Saving Data > Changing Accessible Fields
请注意,虽然实体仍将被标记为 "new",但保存过程将(只要 checkExisting
选项未设置为 false
)测试是否存在具有给定主键的记录,如果有必要,请在继续之前将实体标记为 "non-new",这样您将得到更新而不是插入。
另见 Cookbook > Database Access & ORM > Saving Data > Saving Entities
所以我有 2 个模型:插件和导入。 关联是 Plugins hasOne Imports:
$this->hasOne('Imports', [
'foreignKey' => 'plugin_id'
]);
并导入属于插件:
$this->belongsTo('Plugins', [
'foreignKey' => 'plugin_id',
'joinType' => 'INNER'
]);
我的插件-table 转储如下所示:
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;
我的导入 table 是:
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)
);
现在我烤了两个控制器,一切正常。我可以保存一个导入(稍后将用于导入 xml 文件)并且它链接到一个插件。
但现在我想让 Plugindata 通过我在导入中添加的数据进行更新。
例如,假设我有一个名为 "sale" 的插件,类型为 Wordpress,键为 "wp_sale"。现在我想通过添加导入来更新这个插件。例如更改它的描述或名称。
如果我理解 this 正确,我只需要将我想在插件中更改的数据与 id 一起传递。
但是,当我检查将要保护的 patchEntity 时,插件实体始终为“[new]”=> true,我传递的 ID 消失了。
这是我的控制器的样子:
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']);
}
我的表格是这样的:
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]);
我给 plugin.id 值 1 只是为了测试,因为我想为插件传递一个 id。
我的帖子数据是这样的:
[
'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'
]
]
修补后的实体如下所示:
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'
}
此站点上的许多问题都与关联保存有关。但我想要的是在导入模型中添加新数据时更新关联数据。
其背后的原因是,我希望能够更新我的插件而无需编辑每个插件,只需使用 xml 导入。
如果问题仍然不清楚,请随时提问,我会进一步解释。提前致谢!
编辑:要清楚,我基本上需要使用导入控制器更改插件的数据。
我现在在另一个函数中得到了插件实体,我可以用导入实体保存它。但是,它不会更改插件中的任何内容,所以基本上什么都不做。
在这里加上dependent
,我想这样就可以了。
$this->hasOne('Imports', [
'foreignKey' => 'plugin_id',
'dependent' => true,
]);
链接文档中的示例似乎假设实体的设置方式允许批量分配主键,请参阅
Cookbook > Database Access & ORM > Entities > Mass Assignment
主键需要可访问
默认情况下,烘焙实体不允许批量分配主键,因此您必须注意这一点,例如通过 patchEntitity()
选项覆盖字段可访问状态,例如
$import = $this->Imports->patchEntity(
$import,
$this->request->data,
[
'associated' => [
'Plugins' => [
'accessibleFields' => ['id' => true]
]
]
]
);
另见 Cookbook > Database Access & ORM > Saving Data > Changing Accessible Fields
请注意,虽然实体仍将被标记为 "new",但保存过程将(只要 checkExisting
选项未设置为 false
)测试是否存在具有给定主键的记录,如果有必要,请在继续之前将实体标记为 "non-new",这样您将得到更新而不是插入。
另见 Cookbook > Database Access & ORM > Saving Data > Saving Entities