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