Aldo Bassanini
Aldo Bassanini

Reputation: 485

How can I avoid using findOne in each controller's action?

I have a very basic master -> detail relation:

Relation: Client (1) ---> (n) Comments

I have my controller, but in some actions, I keep repeating the find model with the associated id, and throwing some exception if not found.

    class ClientController extends \yii\web\Controller{

        public function actionViewComment($id) {
                $model = Comment::findOne($id);
                if ($model == null )
                    throw new NotFoundHttpException('The requested page does not exist.');

                return $this->render('view-comment', ['model' => $model]);
        }

        public function actionEditComment($id) {
                $model = Comment::findOne($id);
                if ($model == null )
                    throw new NotFoundHttpException('The requested page does not exist.');
                $model->scenario = 'update';

                if ($model->load(Yii::$app->request->post()) && $model->save()) {
                    return $this->redirect(['view-comment', 'id' => $model->id]);
                } else {
                    return $this->render('edit-comment', ['model' => $model]);
                }
        }
}

I can create a Model method (findOrThrows) to find or throw an exception, but still I have to use it in half my controller actions (could probably be more as the app grows). I was wondering, is there any better way to do this? Some kind of global object that becomes available, based on the Route and the Id, so that the Controller (or the View) can use it?

Upvotes: 0

Views: 277

Answers (1)

arogachev
arogachev

Reputation: 33538

You should look at CRUD generated controller to understand how it's done in Yii.

There is special protected method in each controller called findModel(), for example:

/**
 * @param integer $id
 * @return Post
 * @throws NotFoundHttpException
 */
protected function findModel($id)
{
    if (($model = Post::findOne($id)) !== null) {
        return $model;
    } else {
        throw new NotFoundHttpException('The requested post not exist.');
    }
}

"Global" method will be useless because:

  • Missing autocomplete and highlighting support in IDEs.
  • Sometimes you need to customize exception message to specify exact type of object that does not exist.

Typical usage in actions:

$model = $this->findModel($id);

And you don't care about conditions, throwed exceptions, etc.

Upvotes: 3

Related Questions