CakePHP - 2 контроллера, 1 форма
Мне нужно создать форму обзора. У меня есть 2 модели и 2 контроллера - Продукты и обзоры с отношением 'Products' hasMany 'Reviews', форма обзора будет отображаться на текущей странице продукта (Контроллер продуктов, действие 'view'), и в этой форме будет использоваться другой контроллер (Отзывы).
Также мне нужна проверка для этой формы с отображаемыми ошибками проверки.
В моем контроллере Products view.ctp у меня есть:
// product page stuff...
echo $this->Form->create($model = 'Review', array('url' => '/reviews/add'));
echo $this->Form->input('name', array('label' => 'Your name:'));
echo $this->Form->input('email', array('label' => 'Your e-mail:'));
echo $this->Form->input('message', array('rows' => '6', 'label' => 'Your message:'));
echo $this->Form->hidden('product_id', array('default' => $product['Product']['id']));
echo $this->Form->end('Send');
echo $this->Session->flash();
ReviewsController -> добавить:
public function add() {
if ($this->request->is('post')) {
$this->Review->save($this->request->data);
$this->redirect(array('controller' => 'products', 'action' => 'view', $this->request->data['Review']['product_id'], '#' => 'reviews'));
}
}
Каким-то образом этот ужасный код работает.. частично. Просмотр сохраняется, но ошибки проверки не отображаются.
Если я добавлю оператор If к этому действию:
ReviewsController -> Добавить:
public function add() {
if ($this->request->is('post')) {
if ( $this->Review->save($this->request->data) ){
$this->redirect(array('controller' => 'products', 'action' => 'view', $this->request->data['Review']['product_id'], '#' => 'reviews'));
}}
}
и если форма имеет ошибки и не подтверждает, я получаю сообщение об ошибке MissingView: отсутствует представление
Error: The view for ReviewsController::add() was not found.
У меня вопрос, как правильно справиться с этой ситуацией, чтобы добиться нужной мне функциональности? Должен ли я использовать элементы с действием запроса или мне нужно переместить действие для добавления отзывов в ProductsController?
2 ответа
Одна из ваших проблем заключается в том, что вы выполняете перенаправление только в том случае, если сохранение прошло успешно, поэтому в случае неудачи у вас нет Review / add.ctp, поэтому он выдает ошибку отсутствия представления. Вы должны выполнить перенаправление независимо от того, работает ли сохранение или нет, чтобы вы всегда возвращались на страницу продуктов.
И причина, по которой вы не получите ошибки в полях, заключается в том, что вы делаете перенаправление, поэтому ошибки теряются. Вы можете просто передать ошибки контроллеру продуктов в качестве другого параметра действия.
ReviewsController
public function add() {
if (!empty($this->request->data)) {
$errors = null;
if (!$this->Review->save($this->request->data)) {
$errors = $this->Review->validationErrors;
}
// Always redirect
$this->redirect(array('controller' => 'products', 'action' => 'view', $this->request->data['Review']['product_id'], 'errors' => $errors, '#' => 'reviews'));
}
}
ProductsController
public function view($product_id, $errors = null) {
if (!empty($errors)) {
$this->Review->validationErrors = $errors;
}
}
Конечно, я не знаю, как выглядит весь ваш код, и это не проверено, но идея состоит в том, чтобы передать ошибки проверки модели обзора контроллеру продукта, а затем вручную назначить их обратно модели обзора на странице продуктов.,
Кажется, у тебя нет своего add.ctp
вид создан для обзора.
Не имеет смысла добавлять условие, если вы не планируете делать что-то особенное. Вы всегда хотите, чтобы пользователь вернулся к виду продукта правильно? Это не против, если это подтверждает или нет.
Когда вы используете условие и оно не проверяется, контроллер не будет перенаправлять вас на действие просмотра контроллера продуктов, и он по умолчанию загрузит представление add.ctp.
Просто продолжайте использовать перенаправление, чтобы вернуться к форме.
Используйте свое первое действие добавления. Это правильно. Вы можете добавить сообщение об ошибке, если хотите:
public function add() {
if ($this->request->is('post')) {
if(!$this->Review->save($this->request->data)({
$this->Session->setFlash(__('There was a problem adding the product. Please try again.'));
}
$this->redirect(array('controller' => 'products', 'action' => 'view', $this->request->data['Review']['product_id'], '#' => 'reviews'));
}
Обратите внимание, перенаправление всегда есть.
Он может не отображать красные поля ошибок на каждом входе, потому что вы используете "перенаправление" вместо представления по умолчанию для действия. Во всяком случае, не совсем уверен.