2015-04-09 2 views
0

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

Все проверки входных данных осуществляются в рамках моего запроса StorePostRequest. Проблема в том, что мне нужно проверить, существуют ли указанные теги в базе данных, разрешены только существующие теги. Функция $request->input('tags') возвращает строку с разделенными запятыми значениями, например: Tag1,Tag2,Tag3.

Вот код:

/** 
* Store a newly created resource in storage. 
* 
* @param StorePostRequest $request 
* @return Response 
*/ 
public function store(StorePostRequest $request) 
{ 
    //THIS PIECE OF CODE 
    $tags = explode(',', $request->input('tags')); 
    $tags = Tag::whereIn('title', $tags)->lists('id'); 

    if(count($tags) < 1) 
    { 
     return redirect()->back()->withInput()->withErrors([ trans('tags.min') ]); 
    } 
    else if(count($tags) > 5) 
    { 
     return redirect()->back()->withInput()->withErrors([ trans('tags.max') ]); 
    } 
    //TILL HERE 

    $post = $request->user()->posts()->create([ 
     'slug'   => unique_slug('Post', $request->input('title')), 
     'title'   => $request->input('title'), 
     'description' => $request->input('description'), 
     'summary'  => $request->input('summary'), 
    ]); 

    $post->tags()->attach($tags); 

    return redirect(route('theme.post.show', [$theme->slug, $post->slug]))->with(['success', trans('messages.post.store')]); 
} 

код немного неаккуратно и излишним при использовании его в нескольких контроллерах.

Чтобы решить эту проблему, я создал ValidationServiceProvider, чтобы расширить правила проверки подлинности ядра. Что-то вроде этого:

$this->app['validator']->extend('tags', function ($attribute, $value, $parameters) 
{ 
    $tags = explode(',', $value); 
    $tags = Tag::whereIn('title', $tags)->lists('id'); 

    if(count($tags) < 1 || count($tags) > 5)) 
    { 
     return false; 
    } 
}); 

Довольно аккуратный. Дело в том, что мне все еще нужно иметь доступ к переменной $tags в контроллере (из-за ->attach($tags)).

Есть ли лучший способ решить эту проблему? Или я должен перестать думать и просто использовать (и повторять) код, который у меня есть?

Заранее благодарим заранее, надеюсь, что это принесет какое-то влияние.

+1

Вы можете создать класс '' 'TagsTransformer''', который обрабатывает преобразование из строки в массив и использует это как на контроллере, так и на валидаторе. – vsmoraes

+0

Да, это довольно хорошо. Теперь у меня есть частная функция внутри моего контроллера с именем «processTags()», которая выполняет преобразование и проверку тегов. Это уже намного лучше. – JasonK

ответ

0

Я предполагаю, что вы понимаете использование этого класса, потому что я видел, что вы определили класс StorePostRequest. Так, только для уточнения, метод rules может выглядеть так:

public function rules() 
{ 
    return [ 
     'tags' => ['required', 'tags'] //kb 
    ]; 
} 

Наконец, со всеми инструментами в правильном месте, вы только делаете манипулировать данными в контроллерах, как это:

public function store(StorePostRequest $request) 
{ 
    // at this point, the tags are already validated, so we, proceed get them: 
    $tags = explode(',', $$request->get('tags')); 

    $post = $request->user()->posts()->create([ 
     'slug'   => unique_slug('Post', $request->input('title')), 
     'title'   => $request->input('title'), 
     'description' => $request->input('description'), 
     'summary'  => $request->input('summary'), 
    ]); 

    $post->tags()->attach($tags); 

    return redirect(route('theme.post.show', [$theme->slug, $post->slug]))->with(['success', trans('messages.post.store')]); 
} 

Имейте в виду, что в результате недействительности StorePostRequeststore в функции контроллера он уже проверяет и запускает правила.

Этого достаточно, если вы действительно правильно определили правила StorePostRequest.

+0

Да, я делаю, правила работают нормально. Проблема в том, что мне нужно взорвать строку тегов, проверить, существуют ли они в базе данных, вернуть список (массив id) и затем подсчитать. Поэтому я не могу просто использовать такие правила, как 'tags => 'required | array | min: 1 | max: 5'.'. Кроме того, '$ request-> input ('tags')' возвращает строку, разделенную запятыми, поэтому я не могу использовать attach() на моем контроллере. Извините, если я ошибаюсь :) – JasonK

+0

Я думаю, что вы так сложны. Правило 'tags' уже проверило счетчик существования. Почему бы просто не поместить '$ tags = explode (',', $ tags);' berfore' -> attach ($ tags); 'звонок? Посмотрите отредактированный ответ – manix

+0

'$ request-> input ('tags')' возвращает строку типа Tag1, Tag2, Tag3'. Я должен сначала найти теги в базе данных с этим заголовком, получить их идентификатор в списке, и только тогда я могу использовать '-> attach ($ tag_ids)' – JasonK

Смежные вопросы