RomainB's avatar
Level 13

Store and update request are the same except the unique id. A way to merge?

Hi all, I'm creating my first full project(blog).

With the obsession to write DRY code, I created a CategoryStoreUpdateRequest (and not a StoreRequest + a UpdateRequest) to control the rules to pass and messages to return when store or update route is needed.

I'm using this personnal trick to do this:

public function rules()
    {
        $name_rules = ($this->method() == 'PATCH') // else == 'POST'
            ? 'required|string|max:50|unique:categories,name,'.$this->category->id
            : 'required|string|max:50|unique:categories,name';

        return [
            'name' => $name_rules,
            'parent_id' => 'nullable'
        ];
    }

I just want to know if some of you is seeing an issue to do this that way??

0 likes
4 replies
Cronix's avatar

I do something like that occasionally, however I create a create and update method within the FormRequest. The rules() method just detects the HTTP verb and delegates to the appropriate create/update method, which returns the appropriate rules array for that request. I just think it's easier at a quick glance to see what's going on without having to do ternary operations in your head, and it's very clear what the rules are for each case.

RomainB's avatar
Level 13

Your tip for sure is great when rules became more complicated, I'll probably use this way in future. In this case, they are very short and easily readable/supportable.

To check if I fully understand what you mean. You do something like that?

public function rules()
{
    if ($this->method() == 'PATCH') return $this->updateRules();
    else return $this->createRules();
}

protected function createRules() {
         return [
        'name' => 'required|string|max:50|unique:categories,name',
        'parent_id' => 'nullable'
    ];
}

protected function updateRules() {
         return [
        'name' => 'required|string|max:50|unique:categories,name,'.$this->category->id,
        'parent_id' => 'nullable'
    ];
}
timmy1420's avatar

Maybe this might help.

Here I have an example of UserRequest. By checking the URI from the url if there is an ID uri.

class UserRequest extends FormRequest {

public function rules() {

    if( count( \Request::segments() ) > 1 ) {

        $user_id = \Request::segments()[1];

        return [
            'name' => 'required|min:3|unique:users,name,' . $user_id,
            'address' => 'required|min:3|unique:users,address,' . $user_id,
            'email' => 'indisposable|unique:users,address,' . $user_id,
        ];
    }
// Else, then it's create
 return [
            'name' => 'required|min:3|unique:users,name',
            'address' => 'required|min:3|unique:users,address',
            'email' => 'indisposable|unique:users,address',
        ];
}

}

RomainB's avatar
Level 13

Well, I'm not very sure this is a good way to do. Assuming I add a segment /admin to my panel (which is the case): your conditions is always true.

So if I create my entire project with this rules and no /admin segment.

And then I say to myself "Hmmm, maybe I should add /admin segment" > All my /admin rules crash.

I think catching the HTTP method() is more sure.

Please or to participate in this conversation.