Alex Lomia
Alex Lomia

Reputation: 7235

Why is pluck('id') returning all id-s instead of just one?

The following query returns every Quote's id-s, instead of returning just one:

Quote::find(1)->pluck('id'); // --> [1, 2, 3, 4, ...]

Why is this happening?

Update

Strangely, the query:

Quote::where('id', 1)->pluck('id'); // --> [1]

works as expected.

Upvotes: 1

Views: 648

Answers (2)

patricus
patricus

Reputation: 62248

Quote::find(1) is returning a Quote object, not a Collection of Quotes. You are then calling pluck('id') on that quote object. Since the Quote object doesn't actually have a pluck() method, what this is actually doing is creating a new query builder instance for quotes, and calling pluck on that. It is the same as if you did Quote::pluck('id'). That is why you are getting all of the ids.

Since Quote::find(1) is going to return the Quote object, you don't need to call pluck() on it. You can just access the property.

$quote = Quote::find(1);
echo $quote->id;

Upvotes: 4

Joel Hinz
Joel Hinz

Reputation: 25384

There are (basically) two kinds of pluck() - one that works on collections, and one that works on Builder objects. When you do

Quote::where('id', 1)->pluck('id');

then you have a Builder object, since prior to the plucking you haven't returned anything from the database - you're still building the query. So that works, because the plucking is added to the query and executed.

However, when you do Quote::find(1), you get a Quote object back - which is neither a Builder nor a Collection. Instead, Laravel creates a new query where it tries to pluck values from the database for you, based on which model you're on. In this case, that's the Quote.

This behaviour was changed in 5.2, so in 5.1 you'd get just the column value back - 1 in your case, as expected. But pluck() is taking over what used to be called lists() in earlier versions of Laravel, starting from 5.2. So your results are correct - however confusing.

Upvotes: 4

Related Questions