Yevgeniy Afanasyev
Yevgeniy Afanasyev

Reputation: 41300

How to add / remove elements from array that is in Request

My request looks like this

Array
(
  [name] => Eugene A
  [address] => Array
    (
        [billing] => Array
            (
                [address] => aaa
            )
        [shipping] => Array
            (
                [address] => bbb
            )
    )
)

I need to delete the shipping address. But how?

I can only delete both addresses,

$request->request->remove('address');

but I don't want it.

I want to delete only shipping address, like so

$request->request->remove('address.shipping');

But it is not working for me

Laravel 5.6

Update

Why do I need it?

Easy. I have abstracted out my Form Request validation into a class that is a child to Illuminate\Foundation\Http\FormRequest. I actually have few classes for validation. I call them one by one in a controller like so:

app()->make(CustomerPostRequest::class); // validate Customer information
app()->make(AddressSaveRequest::class); // validate Addresses

Why?

Now I can Mock this requests in unit-tests, and I can have my validation abstracted out. And I can use Address validation in many places.

But Now I need more flexibility. Why?

Because AddressSaveRequest rule looks like this

public function rules(): array
  {
    return [
        'address.*.address'    => [
            'bail',
            'required',
            'string',
        ],
   ...

It validates all addresses. But sometimes I don't want to validate shipping address, if the the chech_box - ship_to_the_same_address is ticked.

But I have my Address validator abstracted in separate file and it is used in many places. There are places where ship_to_the_same_address tick box is not presented.

Thus I cannot use 'required_unless:ship_to_same_address,yes',

And I cannot use

app()->makeWith(AddressSaveRequest::class, ['ship_to_the_same_address ' => 'yes']);

Because Taylor said ...when calling makeWith. In my opinion it should make a new instance each time this method is called because the given parameter array is dynamic.. And it does, and it does not work correctly with app()->instance(AddressSaveRequest::class, $addressSaveRequest); and cannot be mocked in unit tests.

Why Taylor decided it - I seriously don't know.

PS And yes, I know that mocking requests is not recommended.

Upvotes: 4

Views: 7121

Answers (3)

Douwe de Haan
Douwe de Haan

Reputation: 6646

Laravel has a helper method called array_forget, which does exactly what it sounds like:

$requestArray = $request->all();

$newArray = array_forget($requestArray, 'address.shipping')

Documentation

After the edit to the main question with why some inputs of the request are to be deleted, my main answer isn't correct anymore. User Lagbox has the correct answer for the question that was asked.

However, I would like to note that another solution would be to have seperate Request classes with validation. One for placing an order (assuming it is a system where someone can order stuff) where ship_to_same_address is present and another one for things like updating your account, like PlaceOrderRequest and UpdateAccountRequest classes.

Upvotes: 2

lagbox
lagbox

Reputation: 50481

If you were trying to add or remove inputs from the Request itself:

You can add data to the request pretty easily by merging it in and letting Laravel handle which data source is being used:

$request->merge(['input' => 'value']);

That will merge in the input named input into the input source for the Request.

For removing inputs you could try to replace all the inputs without that particular input in the replacement:

$request->replace($request->except('address.shipping'));

Just one idea to try.

Upvotes: 6

Manohar Khadka
Manohar Khadka

Reputation: 2195

Try this:

$request->except(['address.shipping']);

Details: Laravel Request

Upvotes: 2

Related Questions