Laravel Redirects and Validation Logic

Я использую Laravel 4 и ищу элегантный способ обработки ошибок валидации в моих методах контроллера. Все в приведенном ниже коде работает нормально (в реальном коде, который я фактически проверяю. Мой пример просто генерирует исключение для имитации неудачной проверки.) По сути, я хочу получить блок try / catch из каждого контроллера и использовать его в другом методе так что я не повторяю много кода, который очень похож. У меня есть следующий код:

routes.php

Route::resource( 'foo', 'FooController', array('only' => array('create', 'store')));

FooController.php

class FooController extends \BaseController {

public function create()
{
return View::make('foo');
}

public function store(){

try {
// Validation service call goes here.  We'll just force an exception
throw new Exception('Invalid email address!');
} catch (Exception $e) {
return Redirect::back()->withErrors($e->getMessage());
}

// Everything validated so lets save the data
}
}

foo.blade.php

<html>
<body>
<h4>Welcome to page Foo!</h4>

@if($errors->any())
<h4>{{$errors->first()}}</h4>
@endif

{{ Form::open(array('url' => '/foo')) }}

{{ Form::label('email', 'E-Mail Address') }}
{{ Form::text('email', 'example@gmail.com') }}

{{ Form::submit('Submit') }}
{{ Form::close() }}
</body>
</html>

приведенный выше код работает нормально. Исключение из проверки выдается, и мы перенаправлены обратно на страницу с сообщением об ошибке.

Я хочу переместить весь блок try / catch в метод, чтобы убрать беспорядок из метода store (). Что-то вроде этого:

class FooController extends \BaseController {

public function create()
{
return View::make('foo');
}

public function store(){

$this->validateMe();

// Everything validated so lets save the data
}

public function validateMe()
{
try {
// Validation service call goes here.  We'll just force an exception to
// simulate invalid data the sake of the example
throw new Exception('Invalid email address!');
} catch (Exception $e) {
return Redirect::back()->withErrors($e->getMessage());
}
}
}

Эта реализация просто дает мне пустой экран, потому что перенаправление не возвращается в Laravel. Единственный способ перенаправить обратно в форму — это сделать что-то вроде ниже. НО, это не сработает, потому что я никогда не смогу добраться до логики, которая на самом деле сохраняет данные.

public function store(){

return $this->validateMe();

// Everything validated so lets save the data but we can
// never get here because of the return above.  This is bad!
}

0

Решение

Что не так с вашим кодом, так это то, что вы добавили:

public function store(){

return $this->validateMe();

// Everything validated so lets save the data
}

Таким образом, вы всегда возвращаетесь из этой функции, ваш код не выходит за пределы оператора return.

Я бы предложил выполнить проверку / сохранение внутри класса Model, чтобы у вас было меньше кода в контроллере, и его легче изменить. Я сделал свою собственную модель, но вы можете использовать существующий пакет, такой как:
Laravel-Model-Validation


РЕДАКТИРОВАТЬ

Я до сих пор не знаю, почему вы хотите выбрасывать исключения при проверке, что, если есть еще одно недопустимое поле, например имя, адрес электронной почты, вы можете выбросить только одно исключение …

Но если вы настаиваете, просто верните массив всего, что вам нужно

        } catch (Exception $e) {
return ['status' => 'failed',
'validation_object' => $validator,
'exception' => $e,
];
}
//outside of catch, no exceptions occurred,
return ['status' => 'success'];

Тогда в вашем контроллере

public function store(){

$result = $this->validateMe();
if($result['status'] == 'success') {
//code to save in db

return Redirect::back()->with('message', 'saved');
}
else {
return Redirect::back()->withErrors($result['exception']->getMessage());
}
2

Другие решения

Попробуй это

 $inputs = Input::all();

$validator = Validator::make(
array(
'field_name' => $inputs['field_name'],
'field_name' => $inputs['field_name']
),
array(
'field_name' => 'required',
'field_name' => 'required|numeric'
)
);if ($validator->fails())
{
return Redirect::back()->withInput()->withErrors($validator);
}
else
{}
1

Я думаю, что вы пытаетесь подражать $this->validate() Метод в Laravel 5 контроллеров. Я думаю, что суть того, что здесь происходит, заключается в том, что глобальный обработчик ошибок определяется для пользовательского исключения, которое они случайно вызвали HttpResponseException.

Контроллер по умолчанию имеет черта характера (по существу, частичная реализация класса), которая определяет метод, называемый validate() Вот, которые дочерние контроллеры могут вызывать для проверки. Вы также можете использовать черта характера если вы хотите или просто добавьте необходимую логику в ваш базовый контроллер. Практически каждому контроллеру в типичном приложении требуется то же самое.

Когда эта проверка не проходит, метод генерирует вышеупомянутое исключение Вот.
Основная причина, по которой я вижу это пользовательское исключение, заключается в том, что вы можете получить кучу информации о текущем запросе, которая понадобится вам, когда вы поймете исключение на глобальном уровне. Они просто создают ответ перенаправления и сохраняют его в HttpResponseException экземпляр хотя.

Как описано в документы, все, что вам нужно сделать, это написать обработчик ошибок, который перехватит это конкретное исключение и вернет RedirectResponse, который вы включили в исключение. Тот Response используется почти так же, как если бы он был возвращен из метода контроллера напрямую. Конечно, вы можете поместить здесь все виды другой логики, чтобы создать какой-то другой ответ на возвращение.

Я верю в Laravel 5 они делают выше Вот, в коде маршрутизации. Прохождение подхода с обработчиком ошибок означает, что вы бы поймали исключение после того, как оно всплыло еще на несколько уровней, но эффект тот же.

Я знаю, что этот ответ был немногочисленным в коде, но я думаю, что кодовая база Laravel 5 справляется с этим гораздо более изящно, чем все, о чем я мог подумать, и Laravel 4.2 уже, кажется, предоставляет инструменты, которые вам понадобятся для его репликации.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector