dongnius85154 2015-03-22 03:15
浏览 33
已采纳

Laravel验证'独特'无法按预期工作

I'm developing a Help Centre for a site and I've asked the question over at the Laracast Forums to which I haven't had a solution from yet unfortunately, here us the routes/url paths for it:

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');

Category and Section validation are working as expected, but for some reason even though it's the same logic, as far as I can tell, the Article validation doesn't seem to work as expected. Here are my validation rules (I've removed the excess and just left the title field):

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,
        ];

    }

I'll explain just to clarify... for Categories, on INSERT it checks to see if that title already exists, if it does, it doesn't validate. UPDATE does exactly the same except it ignores itself in the check so it can still validate if the title hasn't been changed. So I entered 2 Categories, one called Category 1 and the other Category 2.

Same goes for the Section request, except it only checks for Sections which are in the specified Category you're creating it in. I've tested this out and it works. I can insert foo and bar into Category 1 and foo and bar into Category 2, but if I try to add another foo into either Category 1 or Category 2, it doesn't validate cause it's a duplicate, which is correct. But if I try to update foo in Category 1 to bar it won't allow it, and also if I try to update foo without making any changes, it ignores itself (row) allowing it to pass and not throw a validation error. So everything works as it should for this.

Now for my Article validation, I've used the exact same process/query validation as the Section validation, except changing table/column/variables to suit, like this:

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,
        ];

    }

This should do exactly the same as HelpCentreSectionRequest.php, so allow only one copy of an Article title in each Section of a Category, while allowing an Article of the same title but in a different Section of a Category. That part works fine, however if I insert foo and bar in Category 1 / Section 1, and then update foo to bar it allows the change and to me, it shouldn't since bar already exists in Category 1 / Section 1.

I'm obviously wrong though or else it would work as I expected it too ha. But I just can't see what the problem is?

Here is the database schema just to save any hassle and can confirm table/column names match (again with foreign keys and extra columns removed):

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');
});

I've also checked the if statement in the Article request is definitely firing which was mentioned in the Laracast Forum link at the top. You can also find the Valiation docs here, but for easy reading, this is the main section I am using:

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条回答 默认 最新

  • douqie6454 2015-03-22 08:52
    关注

    Well, first of all your code is hard to analyze, If I were you, I would use array syntax for that:

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

    The second thing is the $method variable. I don't know where it comes from, but assuming it holds the correct value, you should probably change your condition this way:

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

    Last thing, if I try to use one Request class both for store and update, I usually do it this way:

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

    If your method does not work, you could try this above.

    EDIT

    Inside your Request object you can use getMethod() method, for example:

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

    For update you should verify if $method is PUT or PATCH

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 comsol稳态求解器 找不到解,奇异矩阵有1个空方程返回的解不收敛。没有返回所有参数步长;pid控制
  • ¥15 怎么让wx群机器人发送音乐
  • ¥15 fesafe材料库问题
  • ¥35 beats蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功