在 Laravel 5 更新时验证唯一的 Slug
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28662283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Validating a Unique Slug on Update in Laravel 5
提问by Rapture
I currently have a model that has a text field and a slug field.
我目前有一个模型,它有一个文本字段和一个 slug 字段。
I validate that the slug is unique in my form request class:
我验证了 slug 在我的表单请求类中是唯一的:
public function rules()
{
return [
'name' => 'required|min:3',
'slug' => 'required|alpha_dash|unique:questions'
];
}
This works fine on create and properly denies the creation of duplicate slugs. However on my update method, it won't let me save a record because the slug already exists. Of course the slug does exist, but it exists on the record being edited, so I would like to continue to allow it to be saved. However, it should not be able to be changed to a slug on ANOTHER record.
这在创建时运行良好,并正确拒绝创建重复的 slug。但是在我的更新方法中,它不会让我保存记录,因为 slug 已经存在。当然,slug 确实存在,但它存在于正在编辑的记录中,所以我想继续允许它被保存。但是,它不应该能够更改为 ANOTHER 记录上的 slug。
Here's what my update ArticlesController method looks like:
这是我的更新 ArticlesController 方法的样子:
public function update(Article $article, ArticleRequest $request)
{
$article->update($request->all());
return redirect('articles');
}
Is there a way to make this work in L5?
有没有办法在 L5 中完成这项工作?
回答by Marcin Nabia?ek
In unique ruleyou may specify id you want to ignore.
在唯一规则中,您可以指定要忽略的 id。
You can create 2 separate request (one for create and one for update), but you can do it also this way checking if if is set(I assume your update url looks like /questions/2
):
您可以创建 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;
}
}
回答by Purple
Try to modify your rule like following(in form request class):
尝试修改您的规则,如下所示(在表单请求类中):
public function rules()
{
return [
'name' => 'required,min:3',
'slug' => 'required|alpha_dash|unique:categories,slug,'.$this->id')
];
}
It works for me.
这个对我有用。
回答by IndianAg0711
If you must have the ability to update a slug, projects I've worked on usually require it is not editable after creation, then you can use laravel's built in rule to ignore a certain record on the table by primary key.
如果您必须具有更新 slug 的能力,我参与过的项目通常要求它在创建后不可编辑,那么您可以使用 laravel 的内置规则通过主键忽略表上的某个记录。
$rules['slug'] = "required|unique:questions,slug,{$id}";
http://laravel.com/docs/5.0/validationsee "Forcing a unique rule to ignore a given ID"
http://laravel.com/docs/5.0/validation请参阅“强制唯一规则忽略给定 ID”
回答by Amr
Here is how I do it in Laravel 5.3 in details:
以下是我在 Laravel 5.3 中的详细操作方法:
1- Create a new Form Requestclass by executing the next command in your terminal:
1-通过在终端中执行下一个命令来创建一个新的表单请求类:
php artisan make:request ArticleFormRequest
Where ArticleFormRequest
is the name of the form request class. This command will create a file called ArticleFormRequest.php
in app/Http/Requests
directory.
ArticleFormRequest
表单请求类的名称在哪里。此命令将创建一个ArticleFormRequest.php
在app/Http/Requests
目录中调用的文件。
2- Open that created file and remove its content then place the next content in it:
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- In your controller, you can use that ArticleFormRequest
in store()
and update()
methods like this:
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..
}
}
回答by Odin Thunder
In EditArticleRequest:
在EditArticleRequest 中:
public function $rules ()
{
$id = $this->id;
return [
'name' => 'required|min:3',
'slug' => "required|alpha_dash|unique:articles,slug,$id",
];
}
回答by Matthew Malone
As already mentioned you can use the ignore feature in the validator functionality.
如前所述,您可以在验证器功能中使用忽略功能。
Just reference the id of the item you wish to ignore and make sure that when you update you use a patch request!
只需引用您希望忽略的项目的 ID,并确保在更新时使用补丁请求!
See more info here! http://laravel.com/docs/5.0/validation#rule-unique
在这里查看更多信息!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;
}