1
votes

I have got function in controller which looks like this:

//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']);
}

Tables "Users" and "Rooms" are connected in association table. When I run add a new room and I let the user choose who is in the room through the form then it is beeing saved, but when I want to add the first user on my own via $room->users = [$user_field]; its not beeing saved. I'm logging $room object into the file and both objects are the same (after adding user through the form and after adding user through the code). Help me :(

Maybe I should use beforeSave() or afterSave() in model?

SOLUTION I found a solution with Code.Working help. Instead of adding

$this->loadModel('Users');

to the initializie() method i just put it in my createRoom() function.

Final working code looks like this:

//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']);
}
3

3 Answers

0
votes

If you don't reduce the set of users to a specific one, the returning value of find() is always a Query Object: Retrieving Data & Results Sets.

Try this instead to reduce the set of retrieved Users to the first one:

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

Or better, if the 'id' column is your primary key:

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

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

i guess this would help u :

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

with link you can link the user object to the rooms object easily and it is the more beautiful solution i think. Assuming u have set up associations properly ofc!

Good luck :)

0
votes

I think a different method from loading the Model inside your controller could be using the dirty() method.

In your case, you will insert $rooms->dirty('users', true); right after Log::debug($room); and comment the load model of the Users. This will signal the 'users' association of the 'rooms' as dirty, and therefore it will save it when $this->Rooms->save($room) will be called.

Give it a try ;)