Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

iXanadu's avatar

$model->find($id) returns multiple records

Not sure I understand exactly what is going on here. At first I thought it was a blade issue, now I'm not sure. I can kindof duplicate this in tinker.

I noticed that I was incorrectly showing the current user in my index blade instead of the record owner. As a quick cheat, I added some code to resolve the user_id in the record to display that users name. What I get is "two" user names.

            @foreach ($snippets as $snippet)
            <tr>
                <td><a href="{{ action('SnippetsController@edit', [$snippet->id]) }}">{{$snippet->id}}</a></td>
                <td><a href="{{ action('SnippetsController@show', [$snippet->id]) }}">{{$snippet->name}}</a></td>
                <td>{{$snippet->status}}</td>
                <td>{{$snippet->user_id}} {{App\User::find($snippet->id)->lists('name')}}</td>
                <td>{{$snippet->type}}</td>
        @endforeach

This displays two user names, the logged in user and the record owner. ["Admin","Debbie"]

$this->user is set in the constructor to the authorized user. Subsequent calls whether I use the facade or instance "adds" the new record to the collection. This happens in tinker too.

Psy Shell v0.6.1 (PHP 7.0.2 — cli) by Justin Hileman

App\User::find(1)->lists('name');

=> Illuminate\Support\Collection {#812

 all: [
   "Admin",
   "Debbie",
 ],

App\User::find(2)->lists('name');

=> Illuminate\Support\Collection {#811

 all: [
   "Admin",
   "Debbie",
 ],

App\User::where('id','=',1)->lists('name'); => Illuminate\Support\Collection {#820

 all: [
   "Admin",
 ],

The table is setup for id to be auto increment unique

    table->string('type', 24);
        $table->enum('status', ['Active','Archived','Dead','Inactive']);
        $table->text('notes')->nullable();
        $table->string('name', 60);
        $table->string('salutation', 60)->nullable();
        $table->string('fname', 60)->nullable();
        $table->string('lname', 60)->nullable();
        $table->string('title', 60)->nullable();
        $table->date('birthday')->nullable();
        $table->date('anniversary')->nullable();
        $table->string('email', 60)->unique();
        $table->string('emailhome', 60)->nullable();
        $table->string('emailalt1', 60)->nullable();
        $table->string('emailalt2', 60)->nullable();
        $table->string('emailalt3', 60)->nullable();
        $table->string('emailpersonal', 60)->nullable();
        $table->string('password', 60);
        $table->string('address1', 60)->nullable();
        $table->string('address2', 60)->nullable();
        $table->string('city', 60)->nullable();
        $table->string('state', 60)->nullable();
        $table->string('zip', 18)->nullable();
        $table->string('phonehome', 18)->nullable();
        $table->string('phonecell', 18)->nullable();
        $table->string('phonealt', 18)->nullable();
        $table->string('fax', 18)->nullable();
        $table->rememberToken();
        $table->timestamp('lastactivity')->nullable();
        $table->timestamp('lastaccoutactivity')->nullable();
        $table->timestamps();
    });
}

mysql> select id,name from users;

+----+--------+

| id | name |

+----+--------+

| 1 | Admin |

| 2 | Debbie |

+----+--------+

2 rows in set (0.00 sec)

Am I misunderstanding find(), findOrFail(), or is something else going on?

0 likes
13 replies
thomaskim's avatar

That's because you are using the lists() method. Not sure what you are trying to achieve with that. Just do:

App\User::find(1)->name;

There is no lists() method in the model. Because of this, the magic method looks inside the eloquent builder, and you are re-fetching users and getting a collection of users.

tykus's avatar

What you have done is make two queries:

findOrFail() makes a select * from users where id = ?

lists() makes a separate query select name from users

These are not chainable

iXanadu's avatar

@thomaskim

Thanks for this, but it means I'm more ignorant that I initially thought. I thought lists() was how/where you specify which columns you wanted to return. It seems really counterintuitive, that you can use find() and lists together if this is the functionality. I have a lot of code to refactor :(

tykus's avatar

Use this instead:

App\User::select('name')->findOrFail($id);
iXanadu's avatar

@tykus_ikus

Well they are chainable, but not in the way one would think. I mean they pass any smell test, and function, but the results as I am learning are not what I was expecting. This comes from learning on the fly from tutorials. I'm digging into Laravel docs now, and I don't even see a reference to lists in the ORM section.

tykus's avatar

Yeah... it doesn't blow up, but that doesn't mean its right.

Interesting sidenote - I was just looking at the method signature for findOrFail() for the first time since forever... you can pass an array of column names as a second argument; I need to start doing this...

App\User::findOrFail($id, ['name']);
1 like
iXanadu's avatar

@tykus_ikus

You are right, that because it doesn't fail doesn't mean it's right.

I probably have a lot of refactoring to do. I'm grepping now for improper usage. But before I start refactoring based on my obvious lack of understanding on how Laravel's ORM works, do you know where lists() is documented? For instance, my grep is showing this a lot which seems to work, but like you've stated, doesn't mean its right.

$tAry = Snippet::where('type','=','User')->where('user_id','=',$user_id)->get()->lists('slug','name')->toArray();

The biggest stumbling stone for me is differentiating magic from plain code. Code I understand, the magic, is well magic.

iXanadu's avatar

Not to belabor this, but the more I use Laravel the more I find the documentation is not as verbose as I think it should be. Here is "part" of why I misunderstood lists.

https://laravel.com/docs/5.1/queries Retrieving A List Of Column Values

If you would like to retrieve an array containing the values of a single column, you may use the lists method. In this example, we'll retrieve an array of role titles:

$titles = DB::table('roles')->lists('title');

foreach ($titles as $title) {
echo $title;
}
tykus's avatar
tykus
Best Answer
Level 104

There are a number of the Builder methods which accept an array of column names (so you constrain your query before any of these):

->get(['name', 'email'...]);
->find($id, ['name', 'email'...])
->findOrFail($id, ['name', 'email'...])
->firstOrFail(['name', 'email'...])
->first(['name', 'email'...])
1 like
iXanadu's avatar

@tykus_ikus

Thanks for the pointer. I'll start reading the API instead of the documentation. Too much magic in the documentation, and I'm starting to get superstitious. I might not have as much refactoring as I thought. Most of my usage of lists() has been chained onto where/get... kind of logic. The behaviour seems right. From what I'm reading, lists is a method applied to collections, so I "think" that any query type of call that returns a collection can be filtered through lists to specify which columns to return.

I just tested find(1,['id','name']) works great.

tykus's avatar

There are / were a number of lists() methods.

Aside: if you find yourself writing the same query in a number of places, then create scopes, e.g.

// Snippet.php
public function scopeBelongingToUser($query, $id)
{
        return $query->where('type','=','User')->where('user_id','=',$user_id);
// or   return $query->where('type', 'User')->where('user_id', $user_id);  // '=' is implied
// or   return $query->whereType('User')->whereUserId($user_id);  // magic methods
}

// in your controllers etc. 
$tAry = Snippet::belongingToUser($user_id)->get(['slug','name']);

Now you have something that is easier to grok in your controller, and you can continue to chain onto where necessary. MAGIC

iXanadu's avatar

@tykus_ikus

I want to thank you for coaching me through this. This kind of interaction really make the tutorials and documentation clearer. I've been using scopes already.

My grep has identified about 20 instances where I'm using lists(), most of the time correctly. I am leaving for a conference out of state so will be offline for a while, on my return I'll refactor the code to get it right. Glad I found now now, before I push this into production.

Please or to participate in this conversation.