FormRequest for store and update?

Why the heck not.

Posted by lagbox on April 27, 2016 laravel tricks validation

FormRequest for store and update … why not

Often it comes up that people want to reuse their form requests. I am all for this. Most of the time you will be fine with no modifications, until you hit a unique rule :(.

We can actually get past this limitation very easily, when using Restful routes. Luckily for us the rules method is a method, so we can do what ever we need inside of that to adjust our rules.

Here is an example of doing that. As always this is just a simple way, nothing about best practices or what is proper. Just to give you some ideas.

<?php
namespace App\Http\Requests;

use App\Http\Requests\Request;
use Illuminate\Database\Eloquent\Model;

class FormRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|string|max:255|unique:snips,title'. $this->appendUnique('snip'),
            'content' => 'required|string|min:10',
        ];
    }

// I would place this in the base class
    protected $updateMethods = ['PUT', 'PATCH'];

    protected function appendUnique($key, $keyName = 'id')
    {
        if (in_array($this->method(), $this->updateMethods) && $param = $this->route($key)) {
            if ($param instanceof Model) {
                $rt = "{$param->getKey()},{$param->getKeyName()}";
            } else {
                $rt = "{$param},{$keyName}";
            }
            return ','. $rt;
        }
    }
}

What we are doing:

  • Checking if the request method is PUT or PATCH
  • Checking if we have a route parameter to use
  • Checking if that parameter is a model
    • Using the Model’s defined route key and route key name
  • If not a model
    • Using the route parameter as the key and adding the name of the key field to the rule.

Should give you some ideas of what you can do. As always, you dont have to follow this or do it this way, but its simple.