How to validate auto-generated inputs in Laravel?

Today I need some advices on laravel validation. Sure someone can help me on that topic ):

In my project, i have two models : Product and Customer.

Product : id - title - price
Customer : id - company

Prices of the product are updated everyday (are fruits & vegetables).

When a customer is added to the database, the seller and the customer are ok to block the prices for him.
No matter if bananas price is changing, the customer will always pay bananas for the price we define the day he was entered in the database.

So, I create a many to many relation between the 2 models with a pivot table :

Customer_Product : customer_id - product_id - price

Now, I want to update some prices for the customer.
So, I create a form generating input for each product attached to the customer :

<form action="{{ route('update') }}" method="POST">
        @method('put')
        @csrf
        <input type="hidden" name="client" value="{{ $customer->id }}">
        @foreach ($customer->products as $product)
            <div>
                <label for="product{{ $product->id }}">{{ $product->title }}</label>
                <input type="number" step="0.01" name="product{{ $product->id }}" value="{{ $product->pivot->price }}">
            </div>
        @endforeach
        <div>
            <button type="submit">Submit</button>
        </div>

Here is the return of a dd($request->all()) for a customer who has 15 attached products :

^ array:18 [▼
  "_method" => "put"
  "_token" => "b8DNlOcQBtdTlQvwqt88sZYsX4d1bMwBsbGJ1Wj6"
  "customer" => "11"
  "product1" => "100000"
  "product2" => "2000"
  "product3" => "3000"
  "product4" => "142"
  "product5" => "150"
  "product6" => "148"
  "product7" => "105"
  "product8" => "130"
  "product9" => "152"
  "product10" => "109"
  "product11" => "138"
  "product12" => "148"
  "product13" => "129"
  "product14" => "148"
  "product15" => "15000"
]

As I can’t know how many "product" inputs I will have on the form, what is the best way to get and validate thoses datas on serverside with validation rules ?

Thanks for advance for your help

>Solution :

I’d recommend updating the input names to be an array:

<label for="products[{{ $product->id }}][value]">{{ $product->title }}</label>
<input type="number" step="0.01" name="products[{{ $product->id }}][value]" value="{{ $product->pivot->price }}">
<input type="hidden" name="products[{{ $product->id }}][id]" value="{{ $product->id }}">

The above would provide something like:

"products" => [
    1 => [
        "value" => "100",
        "id"    => "1",
    ],
    2 => [
        "value" => "200",
        "id"    => "2",
    ],
    3 => [
        "value" => "300",
        "id"    => "3",
    ],
],

Then, your validation could be:

return [
    'products'         => [
        'array',
    ],
    'products.*.id'    => [
        'required',
        Rule::exists('products', 'id'),
    ],
    'products.*.value' => [
        'required',
        'numeric',
    ],
];

https://laravel.com/docs/9.x/validation#validating-nested-array-input

Leave a Reply