onairmarc's avatar

Class::find($id) returns multiple records

Hi All,

I'm new to Laravel, so if there is something obvious that I'm missing, I do apologize. I'm hacking away at a custom CRM solution and encountering an issue when displaying a single record in a view. What is happening is that when Record ID 1 is displayed inside of the view, everything behaves as I would expect, only that record is returned and displayed. However, when any record above Record ID 1 is attempted to be viewed, for example, Record ID 3, both Record ID 1 and Record ID 3 are returned as a collection. Below is the code that I'm using

Route:

// Contact Classifications
Route::prefix('contact-classification')->controller(CrmClassificationController::class)->group(function () {
    Route::get('', 'index')->name('settings.system-fields.contact-classification.index');
    Route::post('', 'store')->name('settings.system-fields.contact-classification.store');
    Route::get('{crm_classification}', 'show')->name('settings.system-fields.contact-classification.show');
});

CrmClassificationController::show

public function show(CrmClassification $crm_classification)
{
    // dd($crm_classification);
    $crm_collection = CrmClassification::find($crm_classification)->first();
    //dd($crm_collection);
    return view('settings.system-fields.field-details', [
        'field_name' => 'Contact Classification',
        'field_view' => 'settings.system-fields.contact-classification.index',
        'field_value' => $crm_collection,
    ]);
}

When I dd($crm_classification), I'm seeing the correct ID being returned. When I dd($crm_collection), is when I see that multiple records are being returned.

I've tried the following so far: Changing:

$crm_collection = CrmClassification::find($crm_classification)->first();

to

$crm_collection = CrmClassification::find($crm_classification)->last();

This technically works, but I'm afraid that this is not a long term solution and that the original method should be the proper solution.

I've also tried changing

'field_value' => $crm_collection,

to

'field_value' => collect($crm_collection),

but that does not appear to change the outcome.

I'm interested in whatever solutions this community can provide.

Thanks! Marc

0 likes
5 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The issue seems to be with the find() method in the show() function of the CrmClassificationController. The find() method is used to retrieve a single record by its primary key, but in this case, it is being passed an instance of the CrmClassification model instead of the ID.

To fix this issue, you should change the show() function as follows:

public function show($id)
{
    $crm_classification = CrmClassification::find($id);
    
    return view('settings.system-fields.field-details', [
        'field_name' => 'Contact Classification',
        'field_view' => 'settings.system-fields.contact-classification.index',
        'field_value' => $crm_classification,
    ]);
}

By passing the $id directly to the find() method, you will retrieve the correct record based on the ID.

Remember to update the route definition accordingly:

Route::get('{crm_classification}', 'show')->name('settings.system-fields.contact-classification.show');

This should resolve the issue and return a single record instead of a collection.

PovilasKorop's avatar

@onairmarc the way you're using the parameter of show() method is called Route Model Binding: https://laravel.com/docs/10.x/routing#implicit-binding

Which means you ALREADY have that object automatically from Laravel, and you don't need to find it again, Laravel under the hood already performs find($id).

So you can just pass the value along, like this:

public function show(CrmClassification $crm_classification)
{
    return view('settings.system-fields.field-details', [
        'field_name' => 'Contact Classification',
        'field_view' => 'settings.system-fields.contact-classification.index',
        'field_value' => $crm_classification,
    ]);
}
1 like
Snapey's avatar

Lary's dumb answer for the win!

1 like

Please or to participate in this conversation.