skip to Main Content

I am trying to update a row in the pages table.

The slug must be unique in the pages table on the slug and app_id field combined.
i.e. there can be multiple slugs entitled ‘this-is-my-slug’ but they must have unique app_id.

Therefore I have found that formula for the unique rule is:
unique:table,column,except,idColumn,extraColumn,extraColumnValue

I have an update method and getValidationRules method.

public function update($resource,$id,$request){
    $app_id=22;
    $request->validate(
      $this->getValidationRules($id,$app_id)
    );    
    // ...store
}  

When I test for just a unique slug the following works:

public function getValidationRules($id,$app_id){
    return [
        'title'=> 'required',
        'slug'=> 'required|unique:pages,slug,'.$id
    ];
}

However, when I try and add the app_id into the validation rules it returns server error.

public function getValidationRules($id,$app_id){
    return [
        'title'=> 'required',
        'slug'=> 'required|unique:pages,slug,'.$id.',app_id,'.$app_id
    ];
}

I have also tried to use the Rule facade, but that also returns server error. Infact I can’t even get that working for just the ignore id!

public function getValidationRules($id,$app_id){
    return [
        'title'=> 'required',
        'slug'=> [Rule::unique('pages','slug')->where('app_id',$app_id)->ignore($id)]
    ];
}

Any help is much appreciated 🙂

2

Answers


  1. Chosen as BEST ANSWER

    Thanks for the respsonses. It turned out a couple of things were wrong. Firstly if you want to use the Rule facade for the validation rules, make sure you've included it:

    use IlluminateValidationRule; 
    

    The other method for defining the validation rule seems to be limited to the following pattern:

    unique:table,column,except,idColumn
    

    The blog post that I read that showed you could add additional columns was for laravel 7, so i guess that is no longer the case for laravel 9.

    Thanks for your responses and help in the chat!


  2. I recommend you to add your own custom rule.

    First run artisan make:rule SlugWithUniqueAppIdRule
    This will create new file/class inside AppRules called SlugWIthUniqueAppRule.php.

    Next inside, lets add your custom rule and message when error occured.

    public function passes($attribute, $value)
    {
        // I assume you use model Page for table pages
        $app_id = request()->id;
        
        $pageExists = Page::query()
            ->where('slug', $slug)
            ->where('app_id', $app_id)
            ->exists();
    
        return !$pageExists;
    }
    
    public function message()
    {
        return 'The slug must have unique app id.';
    }
    

    Than you can use it inside your validation.

    return [
          'title'=> 'required|string',
         'slug' => new SlugWithUniqueAppIdRule(),
    ];
    

    You can try it again and adjust this custom rule according to your needs.

    Bonus:
    I recommend to move your form request into separate class.
    Run artisan make:request UpdateSlugAppRequest
    And check this newly made file in AppHttpRequests.

    This request class by default will consists of 2 public methods : authorize() and rules().
    Change authorize to return true, or otherwise this route can not be accessed.
    Move your rules array from controller into rules().

    public function rules()
    {
         return [
              'title'=> 'required|string',
             'slug' => new SlugWithUniqueAppIdRule(),
        ];
    }
    

    To use it inside your controller:

    public function update(UpdateSlugAppRequest $request, $resource, $id){
        // this will return validated inputs in array format
        $validated = $request->validated();
    
        // ...store process , move to a ServiceClass
    } 
    

    This will make your controller a lot slimmer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search