Проверка уникального слизня на обновление в Laravel 5

В настоящее время у меня есть модель, в которой есть текстовое поле и поле слива.

Я проверяю, что пул уникален в классе запроса формы:

public function rules()
{
    return [
        'name' => 'required|min:3',
        'slug' => 'required|alpha_dash|unique:questions'
    ];
}

Это отлично работает, создавая и правильно отрицает создание дубликатов слизней. Однако по моему методу обновления он не позволит мне сохранить запись, потому что slug уже существует. Конечно, слизняк существует, но он существует на редактируемой записи, поэтому я хотел бы продолжать разрешать его сохранение. Тем не менее, он не должен быть заменен на слизь в записи ДРУГОЙ.

Вот как выглядит мой метод ArticlesController для обновления:

public function update(Article $article, ArticleRequest $request)
{
    $article->update($request->all());

    return redirect('articles');
}

Есть ли способ сделать эту работу в L5?

Ответ 1

В уникальное правило вы можете указать id, который хотите игнорировать.

Вы можете создать 2 отдельных запроса (один для создания и один для обновления), но вы также можете это сделать, проверяя, установлен ли if (я предполагаю, что ваш URL-адрес обновления выглядит как /questions/2):

public function rules()
{
    $rules = [
        'name' => 'required|min:3',
        'slug' => ['required', 'alpha_dash']
    ];

    $rule = 'unique:questions';

    $segments = $this->segments();
    $id = intval(end($segments));
    if ($id != 0) {  
         $rule .= ',slug,' . $id;
    }
    $rules['slug'][] = $rule;

    return $rules;
    }
}

Ответ 2

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

$rules['slug'] = "required|unique:questions,slug,{$id}";

http://laravel.com/docs/5.0/validation см. "Принуждение уникального правила для игнорирования заданного идентификатора"

Ответ 3

Попробуйте изменить свое правило следующим образом (в классе запроса формы):

public function rules()
{
    return [
      'name'  => 'required,min:3',
      'slug'  => 'required|alpha_dash|unique:categories,slug,'.$this->id')
    ];
}

Это работает для меня.

Ответ 4

Вот как я делаю это в Laravel 5.3 в деталях:

1- Создайте новый класс Запрос формы, выполнив следующую команду в терминале:

php artisan make:request ArticleFormRequest

Где ArticleFormRequest - это имя класса запроса формы. Эта команда создаст файл с именем ArticleFormRequest.php в каталоге app/Http/Requests.

2- Откройте этот созданный файл и удалите его содержимое, а затем разместите в нем следующее содержимое:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Article;

class ArticleFormRequest extends FormRequest
{
    protected $rules = [
        'name' => 'required|min:3',
        'slug' => 'required|alpha_dash|unique:articles,slug',
    ];

    // protected $user; // in case you want the current authenticated user
    protected $request_method;
    protected $id;

    public function __construct(Request $request)
    {
        // $request->user() returns an instance of the authenticated user
        // $this->user = $request->user(); // in case you want the current authenticated user

        // $request->method() returns method of the request (GET, POST, PUT, DELETE, ...)
        $this->request_method = strtoupper($request->method());

        // segments(): Returns an array containing all of the segments for the request path
        // it is important to assign the returned "segments" array to a variable first before using it, otherwise an error will occur
        $segments = $request->segments();
        // note this way will be valid only if "id" of the element is the last segment
        $this->id = end($segments);
    }

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $rules = $this->rules;

        if ($this->request_method == "POST") {
            // do nothing..
        } elseif (in_array($this->request_method, ["PUT", "PATCH"])) {
            $article = Article::find($this->id);

            if ($article) {
                // forcing a unique rule to ignore a given id | https://laravel.com/docs/5.3/validation
                $rules["slug"] = [
                    "required",
                    "alpha_dash",
                    Rule::unique("articles", "slug")->ignore($article->id, "id"),
                ];

                // this is also can be used
                // $rules['slug'] = "required|alpha_dash|unique:articles,slug,$article->id,id";
            }
        }

        return $rules;
    }
}

3- В вашем контроллере вы можете использовать методы ArticleFormRequest в store() и update(), например:

<?php

namespace App\Http\Controllers;

use App\Http\Requests\ArticleFormRequest;

class ArticlesController extends Controller
{


    public function store(ArticleFormRequest $request)
    {
        // your code here..
    }

    public function update(ArticleFormRequest $request, $id)
    {
        // Your code here..
    }

}

Ответ 5

Как уже упоминалось, вы можете использовать функцию игнорирования в функциях проверки.

Просто укажите идентификатор элемента, который вы хотите игнорировать, и убедитесь, что при обновлении вы используете запрос на исправление!

Подробнее см. здесь! http://laravel.com/docs/5.0/validation#rule-unique

protected $rules = [    
    'name' => 'required|min:3',
    'slug' => 'required|alpha_dash|unique:questions'
];

public function rules()
{
    $rules = $this->rules;
    if ($this->isMethod('patch')) 
    {
        $id = $this->articles;
        $rules['slug'] = $rules['slug'].',slug,'.$id;
    }
    return $rules;
}

Ответ 6

В EditArticleRequest:

public function $rules () 
{
    $id = $this->id;

    return [
        'name' => 'required|min:3',
        'slug' => "required|alpha_dash|unique:articles,slug,$id",
    ];
}