Skip to content

[5.4] allow random to return 0 items#20396

Merged
taylorotwell merged 2 commits into
laravel:5.4from
browner12:random-zero
Aug 2, 2017
Merged

[5.4] allow random to return 0 items#20396
taylorotwell merged 2 commits into
laravel:5.4from
browner12:random-zero

Conversation

@browner12

Copy link
Copy Markdown
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
Copy Markdown
Contributor Author

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

@laurencei

laurencei commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

Why would you want a 0 return?

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

@miscbits

miscbits commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

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.

return Arr::random($this->items);
}

if ($amount === 0) {

Copy link
Copy Markdown
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
Copy Markdown
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

miscbits commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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

miscbits commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

that answers that.

@BrandonShar

BrandonShar commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

@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
Copy Markdown
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
Copy Markdown
Contributor

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

@vlakoff

vlakoff commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

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