В настоящее время у меня есть модель, которая имеет текстовое поле и поле слаг.
Я подтверждаю, что слаг является уникальным в моем классе запроса формы:
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?
В уникальное правило Вы можете указать идентификатор, который хотите игнорировать.
Вы можете создать 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;
}
}
Попробуйте изменить ваше правило следующим образом (в классе запроса формы):
public function rules()
{
return [
'name' => 'required,min:3',
'slug' => 'required|alpha_dash|unique:categories,slug,'.$this->id')
];
}
Меня устраивает.
Если у вас должна быть возможность обновить слаг, проекты, над которыми я работал, обычно требуют, чтобы он не редактировался после создания, тогда вы можете использовать встроенное правило laravel, чтобы игнорировать определенную запись в таблице по первичному ключу.
$rules['slug'] = "required|unique:questions,slug,{$id}";
http://laravel.com/docs/5.0/validation
см. «Вынуждение уникального правила игнорировать данный идентификатор»
Вот как я делаю это в 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..
}
}
Как уже упоминалось, вы можете использовать функцию игнорирования в функциональности валидатора.
Просто укажите идентификатор элемента, который вы хотите игнорировать, и убедитесь, что при обновлении вы используете запрос исправления!
Смотрите больше информации здесь! 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;
}
В EditArticleRequest:
public function $rules ()
{
$id = $this->id;
return [
'name' => 'required|min:3',
'slug' => "required|alpha_dash|unique:articles,slug,$id",
];
}