首页 文章

Laravel验证'unique'未按预期工作

提问于
浏览
1

我已经在Laracast Forums问了一下这个问题,但我还没有得到解决方案,不幸的是,我们这里有路径/网址路径:

routes.php

Route::resource('admin/help-centre/category', 'AdminHelpCentreCategoryController');
Route::resource('admin/help-centre/category/{category}/section', 'AdminHelpCentreSectionController');
Route::resource('admin/help-centre/category/{category}/section/{section}/article', 'AdminHelpCentreArticleController');

类别和部分验证按预期工作,但由于某种原因,即使它是相同的逻辑,据我所知,文章验证似乎没有按预期工作 . 这是我的验证规则(我删除了多余的,只是离开了 Headers 字段):

HelpCentreCategoryRequest.php

/* Insert ------------------------------------- */
    $rules = [
        'title' => 'required|min:3|unique:help_centre_categories',
    ];

/* Update ------------------------------------- */
    if ($method == 'PATCH') {

        $rules = [
            'title' => 'required|min:3|unique:help_centre_categories,title,'.$this->category->id,
        ];

    }

HelpCentreSectionRequest.php

/* Insert ------------------------------------- */
    $rules = [
        'title' => 'required|min:3|unique:help_centre_sections,title,NULL,id,category_id,'.$this->category->id,
    ];


/* Update ------------------------------------- */
    if ($method == 'PATCH') {

        $rules = [
            'title' => 'required|min:3|unique:help_centre_sections,title,'.$this->section->id.',id,category_id,'.$this->category->id,
        ];

    }

我将解释只是为了澄清...对于类别,在 INSERT 它检查该 Headers 是否已经存在,如果确实存在,则不进行验证 . UPDATE 完全相同,只是它在检查中忽略了它,所以它仍然可以验证 Headers 是否未被更改 . 所以我输入了2个类别,一个名为 Category 1 ,另一个名为 Category 2 .

对于Section请求也是如此,除了它只检查指定类别中的Sections,你已经对它进行了测试并且它有效 . 我可以将 foobar 插入 Category 1foo 以及 bar 进入 Category 2 ,但是如果我尝试将另一个 foo 添加到 Category 1Category 2 中,它就不会重复,这是正确的 . 但是如果我尝试将 Category 1 中的 foo 更新为 bar 它将不允许它,并且如果我尝试更新_608250而不进行任何更改,它会忽略它自己(行)允许它通过而不会抛出验证错误 . 所以一切都按照应有的方式运作 .

现在,对于我的文章验证,我使用了与Section验证完全相同的进程/查询验证,除了更改表/列/变量以适应,如下所示:

HelpCentreArticleRequest.php

/* Insert ------------------------------------- */
    $rules = [
        'title' => 'required|min:3|unique:help_centre_articles,title,NULL,id,section_id,'.$this->section->id,
    ];


/* Update ------------------------------------- */
    if ($method == 'PATCH') {

        $rules = [
            'title' => 'required|min:3|unique:help_centre_articles,title,'.$this->article->id.',id,section_id,'.$this->section->id,
        ];

    }

这应与 HelpCentreSectionRequest.php 完全相同,因此在类别的每个部分中只允许一个文章 Headers 的副本,同时允许相同 Headers 的文章但在类别的不同部分 . 那部分工作正常,但是如果我在 Category 1 / Section 1 中插入 foobar ,然后将 foo 更新为 bar 它允许更改和我,它不应该因为 bar 已经存在于 Category 1 / Section 1 中 .

我显然是错的,否则它会像我预期的那样工作 . 但我只是看不出有什么问题?

这是数据库模式,只是为了节省任何麻烦,并确认表/列名称匹配(再次删除外键和额外列):

Schema::create('help_centre_categories', function(Blueprint $table)
{
    $table->increments('id')->unsigned();
    $table->string('title');
});

Schema::create('help_centre_sections', function(Blueprint $table)
{
    $table->increments('id')->unsigned();
    $table->integer('category_id')->unsigned();
    $table->string('title');
});

Schema::create('help_centre_articles', function(Blueprint $table)
{
    $table->increments('id')->unsigned();
    $table->integer('category_id')->unsigned();
    $table->integer('section_id')->unsigned();
    $table->string('title');
});

我还检查了条款请求中的 if 语句肯定是在顶部的Laracast论坛链接中提到的 . 您还可以找到Valiation文档here,但为了便于阅读,这是我使用的主要部分:

Adding Additional Where Clauses

You may also specify more conditions that will be added as "where" clauses to the query:

'email' => 'unique:users,email_address,NULL,id,account_id,1'

In the rule above, only rows with an account_id of 1 would be included in the unique check.

1 回答

  • 1

    好吧,首先你的代码很难分析,如果我是你,我会使用数组语法:

    $rules = [
            'title' => ['required'. 'min:3'],
       ];
       $uniqueRule = 'unique:help_centre_categories';
    
       /* Update ------------------------------------- */
        if ($method == 'PATCH') {
           $uniqueRule.='title,'.$this->category->id
        }
        $rules['title'][] = $uniqueRule;
    

    第二件事是 $method 变量 . 我不知道它来自哪里,但假设它具有正确的值,你应该以这种方式改变你的条件:

    if (strtoupper($method) == 'PATCH' || strtoupper($method) == 'PUT') {
     ...
    }
    

    最后,如果我尝试将一个 Request 类用于存储和更新,我通常会这样做:

    $segments = $this->segments();
    $id = intval(end($segments));
    if ($id != 0) {
     // now you know it's update
    }
    

    如果您的方法不起作用,您可以尝试以上方法 .

    EDIT

    Request 对象中,您可以使用 getMethod() 方法,例如:

    public function rules() 
    {
       $method = $this->getMethod();
       if ($method == 'PUT' || $method == 'PATCH') {
            // now you do what you want for update
       }
    
       // rest of code goes here
    }
    

    要进行更新,您应该验证$ method是 PUT 还是 PATCH

相关问题