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

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

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

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

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

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

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

return redirect('articles');
}

Есть ли способ заставить это работать в L5?

12

Решение

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

Вы можете создать 2 отдельных запроса (один для создания и один для обновления), но вы можете сделать это также таким образом, проверяя, если установлен (я предполагаю, что ваш 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;
}
}
3

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

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

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

Меня устраивает.

3

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

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

http://laravel.com/docs/5.0/validation
см. «Вынуждение уникального правила игнорировать данный идентификатор»

2

Вот как я делаю это в 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..
}

}
1

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

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

Смотрите больше информации здесь! 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;
}
0

В EditArticleRequest:

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

return [
'name' => 'required|min:3',
'slug' => "required|alpha_dash|unique:articles,slug,$id",
];
}
0
По вопросам рекламы [email protected]