I would like to be able to save data while providing a where clause.
I have the following code:
$game = $this->Games->newEntity();
if ($this->request->is('post')) {
$game = $this->Games->patchEntity($game, $this->request->data);
if ($this->Games->save($game)) {
$this->Flash->success(__('The game has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The game could not be saved. Please, try again.'));
}
}
I tried this, but it didn't work:
$this->Games->save($game)->innerJoinWith('Leagues', function ($q) use($s) {
return $q->where(['Leagues.user_id' => $s]);
}
)
I suspect having to do a find with a where clause and patch the request data to it?
$game = $this->Games->find()->innerJoinWith('Leagues', function ($q) {
return $q->where(['Leagues.user_id' => $this->Auth->user('id')]);
})
->where(['Games.id' => $id])
->first();
if(! count($game)){
$this->Flash->error(__('The game could not be found.'));
return $this->redirect(['action' => 'index']);
}
if ($this->request->is('post')) {
$game = $this->Games->patchEntity($game, $this->request->data);
if ($this->Games->save($game)) {
$this->Flash->success(__('The game has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The game could not be saved. Please, try again.'));
}
}
Anything simpler?
There is no such saving syntax, retrieving the proper entity in beforehand is the correct way to go, and there isn't really a "simpler" way - however there surely is room for optimization.
Personally I'd use finders to DRY things up, ie create a finder on the GamesTable
that restricts things to specific league users:
public function findForLeagueUser(\Cake\ORM\Query $query, array $options)
{
if (!isset($options['id'])) {
throw new \InvalidArgumentException('The `id` option is invalid or missing.');
}
return $query
->innerJoinWith('Leagues', function (\Cake\ORM\Query $query) use ($options) {
return $query->where([
$this->Leagues->aliasField('user_id') => $options['id']
]);
});
}
and combine things in the controller action:
$game = $this->Games
->find('forLeagueUser', ['id' => $this->Auth->user('id')])
->where(['Games.id' => $id])
->first();
You could also use firstOrFail()
instead, which throws an exception if the record cannot be found, this is what Table::get()
does internally too.
And you could reduce things even further by using a dynamic finder for the games id:
$game = $this->Games
->findById($id)
->find('forLeagueUser', ['id' => $this->Auth->user('id')])
->first();
See also