0

In Laracasts, specifically Laravel 5 Fundamentals, Jeffrey mentioned about using the same Request Class for creating and updating a model. I have tried this but am getting an error:

here is my RequestClass

<?php namespace CRM\Http\Requests;

use CRM\Http\Requests\Request;

class ClientRequest extends Request {

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public $rules = [
            'company'   => 'required|min:3',
            'firstname' => 'required|min:3',
            'lastname'  => 'required|min:3',
            'email'     => 'required|email|unique:clients,email',
            'phone'     => 'required|min:6|phone|unique:clients,phone',
            'address'   => 'required|min:3'
        ];

    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        if($clients = $this->clients){

            $this->rules['email'] .= ','.$clients ;
            $this->rules['phone'] .= ','.$clients ;
        }

        return $this->rules;
    }

    public function messages()
    {
        return ['phone' => 'The phone number is not valid. Please confirm and try again.'];
    }

}

It works fine when I create a new record, but throws an error when I update a record.

Here is the error message

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'company:"BWA"' in 'where clause' (SQL: select count(*) as aggregate from `clients` where `email` = support@example.co.ke and `company:"BWA"` <> {"id":1 and `firstname:"richard"` = lastname:"keep" and `email:"support@example`.`co`.`ke"` = phone:"+27521341661" and `address:"test address"` = deleted_at:null and `created_at:"2015-04-15 08:46:45"` = updated_at:"2015-04-15 09:24:55"})

Here is my controller method

   /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update(Client $client, ClientRequest $request)
    {
        $client->update($request->all());

        return redirect('clients')->with('success', 'Client Updated Successfully');
    }

Anyone with a clue what's going on here?

Bowdzone
  • 3,827
  • 11
  • 39
  • 52
Richie
  • 1,398
  • 1
  • 19
  • 36

2 Answers2

0

In case of editing the record, you need to pass the current record id in set of rules for uniqueness. For your case rules for editing a record can be written like these

public $rules = [
        'company'   => 'required|min:3',
        'firstname' => 'required|min:3',
        'lastname'  => 'required|min:3',
        'email'     => 'required|email|unique:clients,email',
        'phone'     => 'required|min:6|phone|unique:clients,phone,id',
        'address'   => 'required|min:3'
];

Also you would have to write separate rules for the edit and insert case.

Code sample for handling multiple rules in same request class

public function rules()
{
$user = User::find($this->users);
switch($this->method())
{
    case 'GET':
    case 'DELETE':
    {
        return [];
    }
    case 'POST':
    {
        return [
            'user.name.first' => 'required',
            'user.name.last'  => 'required',
            'user.email'      => 'required|email|unique:users,email',
            'user.password'   => 'required|confirmed',
        ];
    }
    case 'PUT':
    case 'PATCH':
    {
        return [
            'user.name.first' => 'required',
            'user.name.last'  => 'required',
            'user.email'      => 'required|email|unique:users,email,'.$user->id,
            'user.password'   => 'required|confirmed',
        ];
    }
    default:break;
}
}
Farooq Khalid
  • 66
  • 1
  • 4
  • I know we used to do that back in Laravel 4.2, but things have changed in Laravel 5. I don't want to have two Request Classes for creating and updating a model. – Richie Apr 15 '15 at 11:17
  • You don't have to make two classes objects to handle this, you can define different set of rules in the same request class based of the request method like if its POST method then define rules for adding a record and if its PATCH method then rules for editing the record. – Farooq Khalid Apr 15 '15 at 11:22
  • I thought this if-statement `if($clients = $this->clients){ ... }` solves that. How can I use your approach? Please write some sample code – Richie Apr 15 '15 at 11:27
  • Updated my answer to add a sample code for adding rules based of the request method – Farooq Khalid Apr 15 '15 at 11:31
  • This part `$user->id` gives me an error message `Trying to get property of non-object` – Richie Apr 15 '15 at 11:50
  • It was just a sample code, you should replace the users object with your client object. The client object should have the record which you want to edit and then set the $client->id in place of $user->id – Farooq Khalid Apr 15 '15 at 11:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75284/discussion-between-richie-and-farooq-khalid). – Richie Apr 15 '15 at 11:55
0

I have managed to solve it. I replaced

    if($clients = $this->clients){

        $this->rules['email'] .= ','.$clients ;
        $this->rules['phone'] .= ','.$clients ;
    }

with

if($this->method == "PUT"){
       $this->rules['email'] .= ','.$this->clients->id ;
       $this->rules['phone'] .= ','.$this->clients->id ;
}
Richie
  • 1,398
  • 1
  • 19
  • 36