0

I send to Laravel this JSON data:

[
  {"name":"...", "description": "..."},
  {"name":"...", "description": "..."}
]

I have a StoreRequest class extends FormRequest:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|string|min:1|max:255',
            'description' => 'nullable|string|max:65535'
        ];
    }
}

In my controller I have this code, but it doesn't work with array:

    public function import(StoreRequest $request) {
        $item = MyModel::create($request);

        return Response::HTTP_OK;
    }

I found this solution to handle arrays in the Request rules():

    public function rules()
    {
        return [
            'name' => 'required|string|min:1|max:255',
            'name.*' => 'required|string|min:1|max:255',
            'description' => 'nullable|string|max:65535'
            'description.*' => 'nullable|string|max:65535'
        ];
    }

How can I update the StoreRequest and/or the import() code to avoide duplicate lines in rules()?

netdjw
  • 5,419
  • 21
  • 88
  • 162
  • Possible duplicate of [How to write validation rule for JSON laravel?](https://stackoverflow.com/questions/57545675/how-to-write-validation-rule-for-json-laravel) – Namoshek Aug 27 '19 at 12:14
  • Yeah, I'm sorry. I overlooked the `[]` and was confused. Please have a look at the linked question and my answer there. – Namoshek Aug 27 '19 at 12:14
  • @Namoshek: I think this isn't a duplicate... In this linked site they use `$validator = Validator::make()` what I don't use, because I have a StoreRequest class. Or if this is a same thing, then I dont understand how can I use this two together. – netdjw Aug 27 '19 at 12:17
  • The rules returned by the `rules()` method are used to create a `Validator` as discussed in the other question. It is the same thing, just an abstraction of it... – Namoshek Aug 27 '19 at 12:20
  • Basically, form request classes (like your `StoreRequest`) are used to extract logic from the controller. You can do exactly the same stuff also with a normal `Request` object and the `Validator` in your controller. It is still recommended to use form requests in order to keep your controller small and simple. – Namoshek Aug 27 '19 at 12:22
  • Isn't there a way to explode my JSON array to data instances and validate one-by-one with a `foreach()` use with the basic `StoreRequest` ? I don't want to rewrite the `StoreRequest` in the controller (like in the linked question)... Mostly because of I have 50+ fields to validate. – netdjw Aug 27 '19 at 12:26
  • I don't get the question. Why don't you just put the validation rules for the request parameters in the `rules()` function? What you currently have in above written question is almost fine, just remove the rules without asterisk (`*`) and move the asterisk of the remaining rules to the front. – Namoshek Aug 27 '19 at 12:28
  • @Namoshek so I have 55 fileds in a JSON object what I need to validate. Of course I can duplicate each lines in the `rules()` but in this case it will be longer, uglier and less maintainable in my opinion. This last is the main reason why I asked this question. I have a validation ruleset to one instance. I think there is a built in way to validate an array of instances with this single ruleset. – netdjw Aug 27 '19 at 12:35
  • ...without modify the ruleset. – netdjw Aug 27 '19 at 12:35
  • That's exactly what my linked answer tries to explain. For an array of objects, you simply use `*` as indicator for the array. – Namoshek Aug 27 '19 at 12:40
  • @Namoshek : I understand that, but the question is: will this `*.` solution working with a non-array objects too? – netdjw Aug 27 '19 at 12:41

1 Answers1

1

As you have an array of data you need to put * first:

public function rules()
{
   return [
       '*.name' => 'required|string|min:1|max:255',
       '*.description' => 'nullable|string|max:65535',
   ];
}
Olivenbaum
  • 971
  • 1
  • 6
  • 17
  • Will this working with a single (non array) objects too? – netdjw Aug 27 '19 at 12:39
  • 2
    No, this would require the rules without `*.`. You can't do both in one ruleset without duplication. IMHO the best way would be to always send an array or use two different FormRequests as they are doing two different things (creating one record vs. creating many records). – Olivenbaum Aug 27 '19 at 12:42