Skip to content
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.4] allow random to return 0 items #20396

Merged
merged 2 commits into from
Aug 2, 2017
Merged

[5.4] allow random to return 0 items #20396

merged 2 commits into from
Aug 2, 2017

Conversation

browner12
Copy link
Contributor

currently passing in a 0 to the Collection->random() method will result in a php error.

this is because it passes the parameter through to the native php array_rand function which specifies the 'second argument needs to be between 1 and the number of elements in the array'.

now if we pass in 0, we will catch that early, and simply return an empty static.

currently passing in a 0 to the `Collection->random()` method will result in a php error.

this is because it passes the parameter through to the native php `array_rand` function which specifies the 'second argument needs to be between 1 and the number of elements in the array'.

now if we pass in 0, we will catch that early, and simply return an empty static.
@browner12
Copy link
Contributor Author

I don't think this is breaking, unless someone was expecting a PHP warning when they passed in zero?

@laurencei
Copy link
Contributor

laurencei commented Aug 2, 2017

Why would you want a 0 return?

edit: seems more logical to throw a InvalidArgumentException if you pass in 0?

@miscbits
Copy link
Contributor

miscbits commented Aug 2, 2017

this wouldn't be a breaking change, but I'm not sure I see the use case being widespread enough to include this in the core. Seems like just bloat since a user could easily do this check on their own and not add an extra check for the majority of people who wouldn't ever need this.

@@ -1089,6 +1089,10 @@ public function random($amount = null)
return Arr::random($this->items);
}

if ($amount === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are 0 items in the collection, we'll never reach this check even though that would seem to be valid with this new logic.

@browner12
Copy link
Contributor Author

here's my use case. I have a User model and a Drink model.

Users can have favorite Drinks.

When I seed the favorite drinks, I want to be able to randomly give them between 0 and 5 favorite drinks.

class FavoriteDrinksSeeder
{
    public function seed(){

        $drinks = \App\Drink::all();

        foreach(\App\User::all() as $user) {
            $user->favoriteDrinks()->attach($drinks->random(rand(0, 5)));
        }
    }
}

@miscbits
Copy link
Contributor

miscbits commented Aug 2, 2017

I see. honestly I think that this is pretty edge though to ever want to give 0 random items. For this case, it'd probably just be better to do

class FavoriteDrinksSeeder
{
    public function seed(){

        $drinks = \App\Drink::all();

        foreach(\App\User::all() as $user) {
            $random_number = rand(0, 5);
            if($random_number) {
                $user->favoriteDrinks()->attach($drinks->random($random_number));
            }
        }
    }
}

I mean it's not as easy for you, but I think the PR in the framework is just bloat.

@browner12
Copy link
Contributor Author

hmm.. i disagree. I would imagine this seeding scenario is common enough.

For example,

A user has made between 0 and 5 orders.

A user has read between 0 and 10 books.

A product has 0 to 3 configuration options.

etc, etc.

@taylorotwell taylorotwell merged commit e9edfa8 into laravel:5.4 Aug 2, 2017
@browner12 browner12 deleted the random-zero branch August 2, 2017 19:47
@miscbits
Copy link
Contributor

miscbits commented Aug 2, 2017

that answers that.

@BrandonShar
Copy link
Contributor

BrandonShar commented Aug 2, 2017

@browner12 there's still a "bug" here that I put in the review. collect()->random(0) will throw throw an InvalidArgumentException "You requested 1 items, but there are only 0 items in the collection."

@browner12
Copy link
Contributor Author

damn you 0 and your false evaluation! 😡

the simple solution seems to be to just move the added check to the top of the function. does that work for everyone?

@BrandonShar
Copy link
Contributor

Makes sense to me. Nothing else to check if all you want back is an empty collection.

@vlakoff
Copy link
Contributor

vlakoff commented Aug 2, 2017

Indeed, previously zero was an unsupported case, just like PHP's array_rand(). But asking for zero items and getting zero items makes sense, so +1 for this PR.

Though, for consistency the same changes should be applied to Arr::random() as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants