【问题标题】:How to save data in cakephp 3 with saving to joinTable如何在 cakephp 3 中保存数据并保存到 joinTable
【发布时间】:2019-06-23 21:53:24
【问题描述】:

我是 php 框架的新手,几天前我已经开始学习 cakephp,但是即使在阅读了 cakephp 食谱关于保存 belongsToMany 关联之后,我仍然不知道如何在我的情况下实现它。

我有三张桌子:
客户:
编号 |名字 |姓氏 |电话 |电子邮件
兴趣:
编号 |正文 |评论 | status_id | created_at
clients_interests:
客户 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;
    }
}

InterestsTable.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 的客户端数据之外的所有数据。并且在保存方法之后,在 interests 表中创建了新的兴趣,但在 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']); ?>

请求数据如下所示:request data

patchEntity() 之后的兴趣实体如下所示:Interest entity

【问题讨论】:

  • 我认为您的请求中没有正确的数据。你能展示给我们看吗?您是否在“保存数据”(book.cakephp.org/3.0/en/orm/saving-data.html) 中看到示例“转换 BelongsToMany 数据”?它可能会告诉你如何构造你的请求数组。
  • @proprit 我更新了我的问题并添加了调试器的屏幕截图。我在那里读到了在 patchEntity() 之后正确编组的关联数据的输入应该如何,但它仍然不起作用

标签: php cakephp


【解决方案1】:

如果您想添加“兴趣”,我认为您的请求数据应该看起来不同。

这里是一个例子,但是很抱歉,我没有测试它,所以你明白了:你必须告诉 CakePHP 你想创建一个兴趣实体,并在里面添加一个客户端信息(就像在book.cakephp.org/3.0/en/orm/saving-data.html的“保存数据”中的“Converting BelongsToMany Data”)。

$data = [
_csrfToken => "...",
'interests' => [
    'text' => 'texttext',
    'comment' => '',
    'created_at' => '2019-01-10',
    'status_id' => 2,
    'clients' => [
        '_ids' => [0],
   ]
];

就个人而言,我从自动烘焙的模板中通过表单助手生成的请求学到了很多东西。

【讨论】:

  • 感谢您的回复。总而言之,我修复了我的输入并将其名称设置为 clients._ids.0 但另一个问题是烘焙功能或我在 phpmyadmin 中创建的数据库导致烘焙的模型和实体的工作不正确。我仍然不知道这个问题的原因是什么,但是我再次从头开始我的项目,并使用纯 sql 命令而不是 phpmyadmin 创建数据库,然后烘烤了所有东西,现在它就像一个魅力:) 谢谢再来一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多