在Laravel 5中验证更新时的唯一Slug

时间:2015-02-22 19:31:27

标签: php laravel laravel-5 laravel-validation laravel-request

我目前有一个包含文本字段和段塞字段的模型。

我验证了slug在我的表单请求类中是唯一的:

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

这在创建时工作正常,并且正确地拒绝创建重复的slugs。但是在我的更新方法中,它不会让我保存记录,因为slug已经存在。当然slug确实存在,但它存在于正在编辑的记录中,所以我想继续允许它被保存。但是,它不应该被改为另一个记录上的slu ..

这是我的更新ArticlesController方法的样子:

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

    return redirect('articles');
}

有没有办法在L5中使这个工作?

6 个答案:

答案 0 :(得分:3)

unique rule中,您可以指定要忽略的ID。

您可以创建2个单独的请求(一个用于创建,一个用于更新),但您也可以这样做检查是否已设置(我假设您的更新网址看起来像/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;
    }
}

答案 1 :(得分:3)

尝试修改您的规则,如下所示(在表单请求类中):

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

它对我有用。

答案 2 :(得分:2)

如果你必须能够更新一个slug,那么我工作过的项目通常要求它在创建后不可编辑,那么你可以使用laravel的内置规则来忽略主键上表中的某个记录。 / p>

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

http://laravel.com/docs/5.0/validation 请参阅“强制使用唯一规则忽略给定ID”

答案 3 :(得分:1)

以下是我在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-在您的控制器中,您可以在ArticleFormRequeststore()方法中使用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..
    }

}

答案 4 :(得分:0)

如前所述,您可以在验证器功能中使用ignore功能。

只需引用您要忽略的项目的ID,并确保在更新时使用补丁请求!

在这里查看更多信息! 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;
}

答案 5 :(得分:0)

EditArticleRequest

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

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