David Dacruz
David Dacruz

Reputation: 169

Unique slug in editing with form request update method Laravel 5.4

I'm having a hard time with this update method. I have a slug field in my news model and it has to be unique. When I update sometimes I may not want to change the slug but the validation of Laravel doesn't let me send my data and when I bypass the validation MySQL won't let me insert into the slug field because of duplicate. This is my update method and validation I have a handleRequest which is just to validate images being uploaded.

NewsController

public function update(CreateNewsRequest $request, $id)
{
        $news = News::findOrFail($id);    
        $data = $this->handleRequest($request);              
        $news->update($data);

    return redirect(route('admin.access.news.index'))->with('message', 'Your news has been updated');
}

CreateNewsRequest

 public function authorize()
{
    //if(access()->hasRole(1) || access()->hasRole(2))
    return true;
}


 public function rules(){     

$news = $this->route()->parameter('news');

$rules = [
    'title' => 'required',
    'slug' => 'required|unique:news',
    'excerpt' => 'required',
    'body' => 'required',
    'category_id' => 'required',
    'image' => 'mimes:gif,bmp,jpeg,jpg,png',
];
    
    switch($this->method()){
    case 'PUT':
    case 'PATCH':
        $rules['slug'] = 'required|unique:news,slug,' .$news;
        break;
    }

return $rules;
}

}

I put this function in NewsController for now

private function handleRequest($request)
{
    if(! $request->published_at ){
            $request->published_at = null;
        }
        
    $data = $request->all();

    if($request->hasFile('image'))
    {
        
        $image = $request->file('image');          
        $fileName = $image->getClientOriginalName();            
        $destination = public_path(config('cms.image.directory'));                      
        $successUploaded = $image->move($destination, $fileName);
        
        if($successUploaded)
        {
            $width = config('cms.image.thumbnail.width');
            $height = config('cms.image.thumbnail.height');
            $extension = $image->getClientOriginalExtension();
            $thumbnail = str_replace(".{$extension}", "_thumb.{$extension}", $fileName);
            Image::make($destination . '/' . $fileName)
                        ->resize($width, $height)
                        ->save($destination . '/' . $thumbnail);
        }
        $data['image'] = $fileName;
    }
    return $data;
}

Upvotes: 1

Views: 2205

Answers (2)

David Dacruz
David Dacruz

Reputation: 169

@AndriyLozynskiy Editing works! Turns out I had a mistake in the form thanks for the help.

I also changed the validation a bit and created an UpdateFormRequest.php

 public function rules(Request $request){

    $news = $this->route('news');

        $rules = [
            'title' => 'required',
            'excerpt' => 'required',
            'body' => 'required',
            'category_id' => 'required',
            'image' => 'mimes:gif,bmp,jpeg,jpg,png',
            'slug' => ($request->slug != $this->slug) ? 'required|alpha_dash|min:5|max:255|unique:news,slug' : ''
        ];

        return $rules;
   }
}

Upvotes: 1

Andriy Lozynskiy
Andriy Lozynskiy

Reputation: 2604

You should ignore your current model by id not by other fields that can be changed in update form. Try this:

switch($this->method()){
    case 'PUT':
    case 'PATCH':
        $id = $this->route('id');
        $rules['slug'] = 'required|unique:news,slug,'.$id;
        break;
    }

Upvotes: 1

Related Questions