【问题标题】:CakePHP 3 - data association before savingCakePHP 3 - 保存前的数据关联
【发布时间】: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']);
}

【问题讨论】:

    标签: php cakephp save


    【解决方案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) 时会保存它。

    试一试;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      相关资源
      最近更新 更多