php - 如何在 cakephp 3 中保存数据并保存到 joinTable
问题描述
我是 php 框架的新手,几天前我已经开始学习 cakephp,但即使在阅读了关于保存 belongsToMany 关联的 cakephp 食谱之后,我仍然不知道如何在我的情况下实现它。
我有三个表:
客户:
id | 名字 | 姓氏 | 电话 | 电子邮件
兴趣:
id | 正文 | 评论 | status_id | created_at
clients_interests:
client_id | 兴趣ID
模型和实体是烘焙的,所以我认为那里没有问题,但这里是代码: ClientsTable.php
class ClientsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('clients');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->belongsToMany('Interests', [
'foreignKey' => 'client_id',
'targetForeignKey' => 'interest_id',
'joinTable' => 'clients_interests'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmptyString('id', 'create');
$validator
->scalar('firstname')
->maxLength('firstname', 64)
->requirePresence('firstname', 'create')
->allowEmptyString('firstname', false);
$validator
->scalar('middlename')
->maxLength('middlename', 64)
->allowEmptyString('middlename');
$validator
->scalar('lastname')
->maxLength('lastname', 64)
->requirePresence('lastname', 'create')
->allowEmptyString('lastname', false);
$validator
->scalar('phone')
->maxLength('phone', 24)
->requirePresence('phone', 'create')
->allowEmptyString('phone', false)
->add('phone', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->email('email')
->allowEmptyString('email');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['email']));
$rules->add($rules->isUnique(['phone']));
return $rules;
}
}
兴趣表.php
class InterestsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('interests');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->belongsTo('Statuses', [
'foreignKey' => 'status_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Clients', [
'foreignKey' => 'interest_id',
'targetForeignKey' => 'client_id',
'joinTable' => 'clients_interests'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmptyString('id', 'create');
$validator
->scalar('text')
->maxLength('text', 128)
->requirePresence('text', 'create')
->allowEmptyString('text', false);
$validator
->scalar('comment')
->maxLength('comment', 128)
->allowEmptyString('comment');
$validator
->date('created_at')
->requirePresence('created_at', 'create')
->allowEmptyDate('created_at', false);
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['status_id'], 'Statuses'));
return $rules;
}
public function getAll($id)
{
$connection = ConnectionManager::get('default');
$results = $connection
->execute('SELECT i.*, s.name status_name, s.classname status_classname FROM interests i INNER JOIN clients_interests ci ON ci.interest_id=i.id AND ci.client_id=:client_id INNER JOIN statuses s ON i.status_id=s.id ORDER BY created_at DESC;', ['client_id' => $id])
->fetchAll('assoc');
return $results;
}
}
ClientsInterestsTable.php
class ClientsInterestsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('clients_interests');
$this->setDisplayField('client_id');
$this->setPrimaryKey(['client_id', 'interest_id']);
$this->belongsTo('Clients', [
'foreignKey' => 'client_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Interests', [
'foreignKey' => 'interest_id',
'joinType' => 'INNER'
]);
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['client_id'], 'Clients'));
$rules->add($rules->existsIn(['interest_id'], 'Interests'));
return $rules;
}
}
客户端实体 - Client.php
class Client extends Entity
{
protected $_accessible = [
'firstname' => true,
'middlename' => true,
'lastname' => true,
'phone' => true,
'email' => true
];
}
兴趣实体 - Interest.php
class Interest extends Entity
{
protected $_accessible = [
'text' => true,
'comment' => true,
'status_id' => true,
'created_at' => true,
'clients_interest' => true,
'status' => true
];
}
ClientsInterests 实体 - ClientsInterests.php
class ClientsInterest extends Entity
{
protected $_accessible = [
'client' => true,
'interest' => true
];
}
然后在我的控制器中,我从一个表单中获取所有数据。patchEntity() 之后的兴趣实体获取除了 joinTable 的客户端数据之外的所有数据。在保存方法之后,创建了新的兴趣表,但clients_interests表中没有新行。我已经从stackoverflow尝试了很多东西,但它没有奏效,因为即使在阅读手册之后我也无法理解保存关联数据的机制。谁能用简单的话解释我如何保存 belongsToMany 相关数据?这是我在InterestsController.php 中保存方法的代码:
public function add()
{
$this->request->allowMethod(['ajax', 'post']);
$this->response->withDisabledCache();
$interest = $this->Interests->newEntity();
$interest = $this->Interests->patchEntity($interest, $this->request->getData(),
['associated'=>['Clients._joinData']]
);
if($this->Interests->save($interest)) {
$result = ['error' => null, 'error_text' => 'SUCCESSFUL'];
} else {
$result = ['error' => null, 'error_text' => 'ERRORS ERRORS ERRORS'];
}
$result = ['error' => null, 'error_text' => 'ERRORS ERRORS ERRORS'];
$this->set('result', $result);
$this->set('_serialize', ['result']);
}
在我的模板中,我使用此输入来获取 client_id:
<?php echo $this->Form->control('clients.0.client_id', ['hidden', 'type'=>'text','id'=>'client-id', 'class'=>'form-control']); ?>
请求数据如下所示:请求数据
patchEntity() 之后的兴趣实体看起来像这样:兴趣实体
解决方案
如果您想添加“兴趣”,我认为您的请求数据应该看起来不同。
这是一个示例,但抱歉,我没有测试它,它是为了让你明白:你必须告诉 CakePHP 你想创建一个兴趣实体,并在里面添加一个客户端信息(就像在“Converting BelongsToMany book.cakephp.org/3.0/en/orm/saving-data.html的“保存数据”中的数据” )。
$data = [
_csrfToken => "...",
'interests' => [
'text' => 'texttext',
'comment' => '',
'created_at' => '2019-01-10',
'status_id' => 2,
'clients' => [
'_ids' => [0],
]
];
就个人而言,我从自动烘焙的模板中通过 Form Helper 生成的请求学到了很多东西。
推荐阅读
- javascript - Electron app.makeSingleInstance 避免多个实例抛出 javascript 错误
- c - 具有大 int 的 Segfault - 内存不足?
- r - 在嵌套循环中运行 R t.test
- reactjs - 反应错误覆盖 - 显示一个错误然后抛出另一个错误以调用代码来处理
- json - 具有动态路径的 Firebase 子安全规则
- http - swi prolog 8.0.2:gziped http
- plot - 邓恩的测试图 - 哪个包?
- android - Tensorflow Lite 模型有时无法检测到对象并崩溃
- azure - AzureWebJobsScriptRoot 变量未在 Azure Functions 上定义,但在本地返回正确的值
- javascript - 如何在 JavaScript 中对任意长的位序列进行 popcount 或计数位