New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.5] change how request only works and remove intersect #18695

Merged
merged 6 commits into from Apr 7, 2017

Conversation

Projects
None yet
@themsaid
Member

themsaid commented Apr 6, 2017

This will make Request::only() work like Collection::only(). Currently these two methods are inconsistent with each other. This will bring them into harmony so that they behave the same.

Given the following payload:

{
    "name": "",
    "category": null,
    "level": 0
}

Output of request()->only('name', 'category', 'level', 'age') will be:

[
    "name"=> "",
    "category"=> null,
    "level"=> 0
]

Prior to this PR, age would have been included in the array returned by only.

@johnRivs

This comment has been minimized.

Show comment
Hide comment
@johnRivs

johnRivs Apr 6, 2017

Don't have any relevant feedback (other than 'I love it') but I wanted to mention how much I love all those red lines in the commit.

😍😍😍

johnRivs commented Apr 6, 2017

Don't have any relevant feedback (other than 'I love it') but I wanted to mention how much I love all those red lines in the commit.

😍😍😍

@sixlive

This comment has been minimized.

Show comment
Hide comment
@sixlive

sixlive Apr 6, 2017

Contributor

I think this makes total sense. Brings consistency and, what I feel, is what you would expect from the only method.

When I build an API that supports PATCH I almost always add a custom macro to add this exact behavior.

Awesome

Contributor

sixlive commented Apr 6, 2017

I think this makes total sense. Brings consistency and, what I feel, is what you would expect from the only method.

When I build an API that supports PATCH I almost always add a custom macro to add this exact behavior.

Awesome

@skyrpex

This comment has been minimized.

Show comment
Hide comment
@skyrpex

skyrpex Apr 6, 2017

Contributor

I didn't know Request did that. I prefer the behavior that this PR brings to the framework.

Contributor

skyrpex commented Apr 6, 2017

I didn't know Request did that. I prefer the behavior that this PR brings to the framework.

@misenhower

This comment has been minimized.

Show comment
Hide comment
@misenhower

misenhower Apr 6, 2017

Contributor

The old behavior can be useful when dealing with checkboxes since an unchecked checkbox will be completely absent from submitted form data (rather than being present and set to false or null, etc.). The old behavior lets you specify all the fields you want to update and ensures they're updated even if they are missing from the form post data.

I like the consistency that this change brings, but it might make certain situations a little more awkward. Is there another method that replicates the old behavior?

Contributor

misenhower commented Apr 6, 2017

The old behavior can be useful when dealing with checkboxes since an unchecked checkbox will be completely absent from submitted form data (rather than being present and set to false or null, etc.). The old behavior lets you specify all the fields you want to update and ensures they're updated even if they are missing from the form post data.

I like the consistency that this change brings, but it might make certain situations a little more awkward. Is there another method that replicates the old behavior?

@boyd91

This comment has been minimized.

Show comment
Hide comment
@boyd91

boyd91 Apr 6, 2017

Yes please, this is definitely the most logical way the only method should work. The way it works now (before this PR) prevents me from using it especially in handling PATCH requests.

When you think about it it doesn't make sense that a method called 'only' will create new values, it should do no more than filter existing values.

boyd91 commented Apr 6, 2017

Yes please, this is definitely the most logical way the only method should work. The way it works now (before this PR) prevents me from using it especially in handling PATCH requests.

When you think about it it doesn't make sense that a method called 'only' will create new values, it should do no more than filter existing values.

@taylorotwell

This comment has been minimized.

Show comment
Hide comment
@taylorotwell

taylorotwell Apr 6, 2017

Member

@misenhower one suggestion I have mentioned internally is to have a pick method which replicates the old behavior to allow people to maintain the old behavior in their applications.

Member

taylorotwell commented Apr 6, 2017

@misenhower one suggestion I have mentioned internally is to have a pick method which replicates the old behavior to allow people to maintain the old behavior in their applications.

@misenhower

This comment has been minimized.

Show comment
Hide comment
@misenhower

misenhower Apr 6, 2017

Contributor

@taylorotwell That sounds good to me. Would be good to have that on the Collection class as well for consistency 👍

Contributor

misenhower commented Apr 6, 2017

@taylorotwell That sounds good to me. Would be good to have that on the Collection class as well for consistency 👍

@themsaid

This comment has been minimized.

Show comment
Hide comment
@themsaid

themsaid Apr 6, 2017

Member

Following on @taylorotwell's comment, this will also make it easier for people while upgrading to just replace only() with pick() if they want to keep the old behaviour.

Member

themsaid commented Apr 6, 2017

Following on @taylorotwell's comment, this will also make it easier for people while upgrading to just replace only() with pick() if they want to keep the old behaviour.

@laurencei

This comment has been minimized.

Show comment
Hide comment
@laurencei

laurencei Apr 6, 2017

Member

@misenhower - as a side point you can solve your issue another way:

<input type="hidden" name="the_checkbox" value="0" />
<input type="checkbox" name="the_checkbox" value="1" />

That means an unchecked checkbox will still come through your form request as 0 - even though they are not ticked. I use this in all my projects - works flawlessly.

http://stackoverflow.com/a/476581/1317935

Might mean you can refactor your code to use that, rather than refactor to use the new pick().

Ping me on slack if you want to discuss further (dont want to derail this PR)

Member

laurencei commented Apr 6, 2017

@misenhower - as a side point you can solve your issue another way:

<input type="hidden" name="the_checkbox" value="0" />
<input type="checkbox" name="the_checkbox" value="1" />

That means an unchecked checkbox will still come through your form request as 0 - even though they are not ticked. I use this in all my projects - works flawlessly.

http://stackoverflow.com/a/476581/1317935

Might mean you can refactor your code to use that, rather than refactor to use the new pick().

Ping me on slack if you want to discuss further (dont want to derail this PR)

@juukie

This comment has been minimized.

Show comment
Hide comment
@juukie

juukie Apr 6, 2017

Contributor

@laurencei that is a way to solve it but it feels akward to me.

I'd prefer to have the pick() method to be added so I don't have to mess with frontend code. Replacing only() with pick() in the backend will be a lot easier.

Contributor

juukie commented Apr 6, 2017

@laurencei that is a way to solve it but it feels akward to me.

I'd prefer to have the pick() method to be added so I don't have to mess with frontend code. Replacing only() with pick() in the backend will be a lot easier.

@misenhower

This comment has been minimized.

Show comment
Hide comment
@misenhower

misenhower Apr 6, 2017

Contributor

@laurencei Yeah, that's a good option too, I've had to do that in a few situations as well. It works but feels a little hacky (and it adds duplicated fields to query strings if you're submitting via GET). Good to have both options available 😃

Contributor

misenhower commented Apr 6, 2017

@laurencei Yeah, that's a good option too, I've had to do that in a few situations as well. It works but feels a little hacky (and it adds duplicated fields to query strings if you're submitting via GET). Good to have both options available 😃

@Keoghan

This comment has been minimized.

Show comment
Hide comment
@Keoghan

Keoghan commented Apr 6, 2017

👍

@meyyappanv

This comment has been minimized.

Show comment
Hide comment
@meyyappanv

meyyappanv commented Apr 7, 2017

+1

@michaeldyrynda

This comment has been minimized.

Show comment
Hide comment
@michaeldyrynda

michaeldyrynda Apr 7, 2017

Contributor

Not only consistency within similarly named methods in the framework, but more coherent behaviour. I think it a bit odd that telling a request you want only certain keys, and getting a key that doesn't exist is a bit rough.

👍

Contributor

michaeldyrynda commented Apr 7, 2017

Not only consistency within similarly named methods in the framework, but more coherent behaviour. I think it a bit odd that telling a request you want only certain keys, and getting a key that doesn't exist is a bit rough.

👍

Use anonymous class as place-holder.
Incoming HTTP requests would have no way to trick this place-holder or even get lucky.
@taylorotwell

This comment has been minimized.

Show comment
Hide comment
@taylorotwell

taylorotwell Apr 7, 2017

Member

Updated the $placeholder to just be an empty anonymous class since HTTP requests have no way to pass in an object like that and we can do a strict equality check. Even though it would be very rare to guess a str_random just feels safer since its now totally impossible.

Member

taylorotwell commented Apr 7, 2017

Updated the $placeholder to just be an empty anonymous class since HTTP requests have no way to pass in an object like that and we can do a strict equality check. Even though it would be very rare to guess a str_random just feels safer since its now totally impossible.

@JosephSilber

This comment has been minimized.

Show comment
Hide comment
@JosephSilber

JosephSilber Apr 7, 2017

Contributor

$placeholder = new stdClass; should also work, and would make StyleCI happy without another line break.

Contributor

JosephSilber commented Apr 7, 2017

$placeholder = new stdClass; should also work, and would make StyleCI happy without another line break.

@pankitgami

This comment has been minimized.

Show comment
Hide comment
@pankitgami

pankitgami commented Apr 7, 2017

+1

@themsaid

This comment has been minimized.

Show comment
Hide comment
@themsaid

themsaid Apr 7, 2017

Member

Switched to using stdClass.

Member

themsaid commented Apr 7, 2017

Switched to using stdClass.

@RDelorier

This comment has been minimized.

Show comment
Hide comment
@RDelorier

RDelorier Apr 7, 2017

Contributor

One day this is going to happen 😌 #15758

Contributor

RDelorier commented Apr 7, 2017

One day this is going to happen 😌 #15758

@taylorotwell taylorotwell merged commit 542d347 into laravel:master Apr 7, 2017

1 check passed

continuous-integration/styleci/pr The StyleCI analysis has passed
Details
@OwenMelbz

This comment has been minimized.

Show comment
Hide comment
@OwenMelbz

OwenMelbz Apr 25, 2017

Contributor

Only something to consider from a "social responsibility" point of view.

Recently theres been a surge of tweets/blog posts, video tutorials including ones from @adamwathan suggesting the benefits of "Intersect"

Now removing it will lead to killing lots of recently released blog posts/resources which could confuse newcomers.

Contributor

OwenMelbz commented Apr 25, 2017

Only something to consider from a "social responsibility" point of view.

Recently theres been a surge of tweets/blog posts, video tutorials including ones from @adamwathan suggesting the benefits of "Intersect"

Now removing it will lead to killing lots of recently released blog posts/resources which could confuse newcomers.

@michaeldyrynda

This comment has been minimized.

Show comment
Hide comment
@michaeldyrynda

michaeldyrynda Apr 25, 2017

Contributor

Happens all the time, just means it's time for new blog content!

Contributor

michaeldyrynda commented Apr 25, 2017

Happens all the time, just means it's time for new blog content!

@ejunker

This comment has been minimized.

Show comment
Hide comment
@ejunker

ejunker Jun 14, 2017

@themsaid are you going to add the pick() method discussed in this issue? It would make it easier for people to upgrade because they could replace their uses of only() with pick() and not have to worry about their code breaking.

ejunker commented Jun 14, 2017

@themsaid are you going to add the pick() method discussed in this issue? It would make it easier for people to upgrade because they could replace their uses of only() with pick() and not have to worry about their code breaking.

@vinterskogen

This comment has been minimized.

Show comment
Hide comment
@vinterskogen

vinterskogen Jul 30, 2017

Contributor

@themsaid, are there any solutions of using intersect method with correct behavior in 5.4? In 5.4 intersect method doesn't work properly in come cases - check the issue #20315.

Contributor

vinterskogen commented Jul 30, 2017

@themsaid, are there any solutions of using intersect method with correct behavior in 5.4? In 5.4 intersect method doesn't work properly in come cases - check the issue #20315.

@kz

This comment has been minimized.

Show comment
Hide comment
@kz

kz Jul 31, 2017

@vinterskogen Given the recent changes with this topic, it's best to use a macro and wait for Laravel 5.5. You can find an example of a macro with a person's expected version of intersectOnly here: #15758 (comment)

kz commented Jul 31, 2017

@vinterskogen Given the recent changes with this topic, it's best to use a macro and wait for Laravel 5.5. You can find an example of a macro with a person's expected version of intersectOnly here: #15758 (comment)

@stukjedevelopment

This comment has been minimized.

Show comment
Hide comment
@stukjedevelopment

stukjedevelopment Aug 22, 2017

Not sure if I'm at the right place, but will this fix this problem as well:
When I pick rules from a FormRequest which contain a validation for an array as well, I get this strange wildcard as key in my output as well. Both for the only() and intersect() method.

$rules = [
            'title' => 'required|min:20',
            'channels' => 'min:1',
            'channels.*.account' => ‘required’
        ];

$request->all()

array:9 [▼
  "_method" => "PUT"
  "_token" => "BFcddbCGLshZtzB75XjjaM1LXAs4707zH49b4Li2"
  "title" => “Some Title“
  "channels" => array:2 [▼
    1 => array:1 [▼
      "account" => "1"
    ]
    2 => array:1 [▼
      "account" => "2"
    ]
  ]
]

$request->intersect(array_keys($rules));

array:5 [▼
  "title" => “Some Title“
  "channels" => array:3 [▼
    1 => array:1 [▼
      "account" => "1"
    ]
    2 => array:1 [▼
      "account" => "2"
    ]
    "*" => array:1 [▼
      "account" => array:2 [▶]
    ]
  ]
]

stukjedevelopment commented Aug 22, 2017

Not sure if I'm at the right place, but will this fix this problem as well:
When I pick rules from a FormRequest which contain a validation for an array as well, I get this strange wildcard as key in my output as well. Both for the only() and intersect() method.

$rules = [
            'title' => 'required|min:20',
            'channels' => 'min:1',
            'channels.*.account' => ‘required’
        ];

$request->all()

array:9 [▼
  "_method" => "PUT"
  "_token" => "BFcddbCGLshZtzB75XjjaM1LXAs4707zH49b4Li2"
  "title" => “Some Title“
  "channels" => array:2 [▼
    1 => array:1 [▼
      "account" => "1"
    ]
    2 => array:1 [▼
      "account" => "2"
    ]
  ]
]

$request->intersect(array_keys($rules));

array:5 [▼
  "title" => “Some Title“
  "channels" => array:3 [▼
    1 => array:1 [▼
      "account" => "1"
    ]
    2 => array:1 [▼
      "account" => "2"
    ]
    "*" => array:1 [▼
      "account" => array:2 [▶]
    ]
  ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment