CakePHP 3 - 保存前的数据关联

Posted

技术标签:

【中文标题】CakePHP 3 - 保存前的数据关联【英文标题】:CakePHP 3 - data association before saving 【发布时间】:2016-06-28 17:20:36 【问题描述】:

我在控制器中有如下功能:

//Create room
public function createRoom()
    $room = $this->Rooms->newEntity();
    if($this->request->is('post'))
        $room = $this->Rooms->patchEntity($room, $this->request->data);
        $user_field = $this->Rooms->Users->find()->where(['id' => $this->Auth->user('id')]);
        $room->users = [$user_field];
        $room->current = 1;
        $room->owner_id = $this->Auth->user('id');
        Log::debug($room);
        if($this->Rooms->save($room))
            $this->Flash->success('You have created a new room.');
            return $this->redirect(['action' => 'index']);
        
        else
            $this->Flash->error('Error creating new room.');
        
    
    $games = $this->Rooms->Games->find('list', ['limit' => 200, 'keyField' => 'id', 'valueField' => 'name']);
    $this->set(compact('room', 'games', 'users'));
    $this->set('_serialize', ['room']);

表“用户”和“房间”在关联表中连接。当我运行添加新房间并让用户通过表单选择房间中的人时,它正在保存,但是当我想通过 $room->users = [$user_field] 自己添加第一个用户时;它没有被保存。我正在将 $room 对象记录到文件中,并且两个对象都是相同的(在通过表单添加用户和通过代码添加用户之后)。帮帮我:(

也许我应该在模型中使用 beforeSave() 或 afterSave()?

解决方案 我在 Code.Working 帮助下找到了解决方案。 而不是添加

$this->loadModel('Users');

对于 initializie() 方法,我只是将它放在我的 createRoom() 函数中。

最终的工作代码如下所示:

//Create room
public function createRoom()
    $this->loadModel('Users');
    $room = $this->Rooms->newEntity();
    if($this->request->is('post'))
        $room = $this->Rooms->patchEntity($room, $this->request->data);
        $user_field = $this->Users->get($this->Auth->user('id'));
        $room->users = [$user_field];
        $room->current = 1;
        $room->owner_id = $this->Auth->user('id');
        Log::debug($room);
        if($this->Rooms->save($room))
            $this->Flash->success('You have created a new room.');
            return $this->redirect(['action' => 'index']);
        
        else
            $this->Flash->error('Error creating new room.');
        
    
    $games = $this->Rooms->Games->find('list', ['limit' => 200, 'keyField' => 'id', 'valueField' => 'name']);
    $this->set(compact('room', 'games', 'users'));
    $this->set('_serialize', ['room']);

【问题讨论】:

【参考方案1】:

如果不将用户集减少到特定的用户,find() 的返回值始终是一个查询对象:Retrieving Data & Results Sets。

尝试使用此方法将检索到的用户集减少到第一个:

$user_field = $this->Rooms->Users->find()->where(['id' => $this->Auth->user('id')])->first();

或者更好,如果 'id' 列是您的主键:

// In the initialize() method
$this->loadModel('Users');

// And in the action:
$user_field = $this->Users->get($this->Auth->user('id'));

【讨论】:

嘿,谢谢你的回答。我将您的解决方案放入我的控制器的地方出现以下错误:调用布尔值的成员函数 user()。我该怎么办? 您是否加载了身份验证插件?将 Auth 保存在变量中并在视图中保存 print_r() 可能会有所帮助。像 $this->set('auth', $this->Auth);在视图中:print_r($auth);【参考方案2】:

我想这会对你有所帮助:

http://api.cakephp.org/3.2/class-Cake.ORM.Association.BelongsToMany.html#_link

通过链接,您可以轻松地将用户对象链接到房间对象,这是我认为更漂亮的解决方案。假设你已经正确地建立了协会!

祝你好运:)

【讨论】:

奇怪的是我后来设法“取消链接”用户,但我无法让“链接”工作。我会花更多的时间在这上面,我会试着找到答案。感谢您的提示!【参考方案3】:

我认为与在控制器中加载模型不同的方法是使用dirty() 方法。

在您的情况下,您将在Log::debug($room); 之后插入$rooms->dirty('users', true); 并注释用户的负载模型。这会将“房间”的“用户”关联表示为dirty,因此在调用$this->Rooms->save($room) 时会保存它。

试一试;)

【讨论】:

以上是关于CakePHP 3 - 保存前的数据关联的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 3.0 保存我的关联数据

CakePHP 3 跨 2 个表保存关联数据

Cakephp 3 保存关联属于ToMany

在 Cakephp 3 中保存关联模型

CakePHP 3.x - 保存这些表的关联数据和表单输入

CakePHP 3 保存 BelongsToMany 关联未知类型“”错误