11

I am using form request validation and there are some rules that needs external values as a parameters.

Here are my validation rules for editing a business profile inside a form request class,

public function rules()
{
    return [
        'name' => 'required|unique:businesses,name,'.$business->id,
        'url' => 'required|url|unique:businesses'
    ];
}

I can use this on the controller by type hinting it.

public function postBusinessEdit(BusinessEditRequest $request, Business $business)
{
    //
}

But how to pass the $business object as a parameter to the rules method?

2
  • import the model(i assume $business is a model) into your request class & get the object manually Commented Jul 16, 2015 at 1:44
  • @NehalHasnayeen yes the business is a model but it is type hinted on to the controller method that uses route model bindings. Commented Jul 16, 2015 at 1:58

6 Answers 6

10

Lets say this is your model binding:

$router->model('business', 'App\Business');

Then you can reference the Business class from within the FormRequest object like this:

public function rules()
{
    $business = $this->route()->getParameter('business');
    // rest of the code
}

Note that if you use your form request both for create and update validation, while creating the record, the business variable will be null because your object does not exists yet. So take care to make the needed checks before referencing the object properties or methods.

Sign up to request clarification or add additional context in comments.

1 Comment

you can do shorter $this->route('business')
9

There can be many ways to achieve this. I do it as below.

You can have a hidden field 'id' in your business form like bellow,

{!! Form::hidden('id', $business->id) !!}

and you can retrieve this id in FormRequest as below,

public function rules()
{
    $businessId = $this->input('id');

    return [
        'name' => 'required|unique:businesses,name,'.$businessId,
        'url' => 'required|url|unique:businesses'
    ];
}

1 Comment

I think this answer is simpler than the accepted answer.
5

For those who switched to laravel 5 :

public function rules()
{
    $business = $this->route('business');
    // rest of the code
}

Comments

1

Let say if we have a scenario like we want to change our validation rules depends on the type that we pass in with the route. For example:

app.dev/business/{type}

For different type of business, we have different validation rules. All we need to do is type-hint the request on your controller method.

public function store(StoreBusiness $request)
{
    // The incoming request is valid...
}

For the custom form request

class StoreBussiness extends FormRequest
{

    public function rules()
    {
        $type = $this->route()->parameter('type');

        $rules = [];
        if ($type === 'a') {
        }

        return rules;
    }
}

Comments

1

In Laravel 5.5 at least (haven't checked older versions), once you did your explicit binding (https://laravel.com/docs/5.5/routing#route-model-binding), you can get your model directly through $this:

class StoreBussiness extends FormRequest
{

    public function rules()
    {
        $rules = [];
        if ($this->type === 'a') {
        }

        return rules;
    }
}

Comments

1

Since Laravel 5.6 you may type hint it in the rules method:

public function rules(Business $business)
{
    return [
        'name' => 'required|unique:businesses,name,'.$business->id,
        'url' => 'required|url|unique:businesses'
    ];
}

See the docs for more:

You may type-hint any dependencies you need within the rules method's signature. They will automatically be resolved via the Laravel service container.

4 Comments

Adam ... for example, if you have public function update(BusinessUpdateRequest $request, Business $business) {...} on the BusinessController.php, how do you pass the $business to the BusinessUpdateRequest.php so you can uses this parameter on the "rules" method like you do on your example???
@zacktagnan you need to bind $business to the server container. It will be resolved automatically :)
Adam ... Sorry, but I don't know how to "bind $business to the server container" Could you do an example of that?
@zacktagnan create a service provider and bind your class. Read laravel.com/docs/7.x/container and laravel.com/docs/7.x/providers#the-register-method to get started

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.