Гов*окод или нет?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

Гов*окод или нет?

Сообщение Nicolai6120 »

Есть такой код...

Код: Выделить всё

    public function actionCreate()
    {
        $productManager = new ProductManager();
        if ($productManager->save()) {
            return $this->redirect(['index']);
        }

        return $this->render('create', [
            'product' => $productManager->getProduct(),
        ]);
    }

    public function actionUpdate($id)
    {
        $productManager = new ProductManager(['productId' => $id]);
        if ($productManager->save()) {
            return $this->redirect(['index']);
        }

        return $this->render('update', [
            'product' => $productManager->getProduct(),
        ]);
    }

    public function actionDelete($id)
    {
        $productManager = new ProductManager(['productId' => $id]);
        if ($productManager->delete()) {
            return $this->redirect(['index']);
        }

        return $this->redirect(['index']);
    }
и вот такое внутри мэнеджера:

Код: Выделить всё

    public function save()
    {
        $product = $this->product;
        $transaction = Yii::$app->db->beginTransaction();
        try {
            if (!$product->load(Yii::$app->request->post()) || !$product->save()) {
                throw new ErrorException('Unable to save product.');
            }

            ProductPhoto::deleteAll([
                'product_id' => $product->id,
                'is_main' => true
            ]);

            $photo = new ProductPhoto();
            $photo->product_id = $product->id;
            $photo->url = $product->mainPhotoUrl;
            $photo->is_main = true;
            if (!$photo->save()) {
                throw new ErrorException('Unable to save attached photo.');
            }

            $transaction->commit();

        } catch (\Exception $e) {
            $transaction->rollBack();
            return false;
        }

        return true;
    }
Поясню, чем это было вызвано. Часто замечаю что повторяюсь в котроллерах. Также эти методы нужно расшарить между несколькими контроллерами. В итоге пришел к такому методу save и выделению такого менеджера. Мне говорят что плохо то, что я работаю с реквестом внутри своего класса. И я в общем-то согласен... Это похоже на контроллер. НО может в таком подходе было что-то здравое? Если нет, буду переписывать...
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

Re: Гов*окод или нет?

Сообщение Nicolai6120 »

П.С. про существование standalone actions я знаю
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Гов*окод или нет?

Сообщение ElisDN »

Труднотестируемый говнокод с синглтонами:

Код: Выделить всё

$manager = new ProductManager();
if ($manager->save()) {
    return $this->redirect(...);
}

$manager = new ProductManager($id);
if ($manager->save()) {
    return $this->redirect(...);
}
Труднотестируемый полуговнокод с явной передачей всего реквеста:

Код: Выделить всё

$manager = new ProductManager();
if ($id = $manager->create(Yii::$app->request)) {
    return $this->redirect(['view', 'id' => $id]);
}

$manager = new ProductManager();
if ($manager->edit($id, Yii::$app->request)) {
    return $this->redirect(...);
}
Легкотестируемый код с разделением обязанностей, без передачи реквеста и без return false:

Код: Выделить всё

$form = new CreateForm();
if ($form->load(Yii::$app->request->post()) && $form->validate()) {
    try {
        $id = $this->manager->create($form);
        return $this->redirect(...);
    } catch (\DomainException $e) {
        Yii::$app->errorHandler->logException($e);
        Yii::$app->session->setFlash('error', $e->getMessage());
    }
}
return $this->render(...);

Код: Выделить всё

$product = $this->loadModel($id);
$form = new EditForm($product);
if ($form->load(Yii::$app->request->post()) && $form->validate()) {
    try {
        $this->manager->edit($product->id, $form);
        return $this->redirect(...);
    } catch (\DomainException $e) {
        Yii::$app->errorHandler->logException($e);
        Yii::$app->session->setFlash('error', $e->getMessage());
    }
}
return $this->render(...);
kukuruku
Сообщения: 1318
Зарегистрирован: 2011.02.14, 11:36

Re: Гов*окод или нет?

Сообщение kukuruku »

а как правильно?
плюс еще вопрос-с куки как правильно работать в моделях? передавать request или в модели обращаться к Yii::$app->request
Nicolai6120
Сообщения: 143
Зарегистрирован: 2014.08.13, 15:08

Re: Гов*окод или нет?

Сообщение Nicolai6120 »

Огромное спасибо!!! Жалко конечно что от лапши из трай-кэтчей в контроллерах избавиться не получится. Видимо так и должно быть.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Гов*окод или нет?

Сообщение ElisDN »

kukuruku писал(а): 2018.04.21, 08:53 плюс еще вопрос-с куки как правильно работать в моделях? передавать request или в модели обращаться к Yii::$app->request
Реквест, куки, сессия и т.п. - это уровень контроллера. В методы объектов модели передавайте значения из кук и результат метода записывайте в куки.
Ответить