Home > Software engineering >  Laravel apiResource to fetch record by field other than id
Laravel apiResource to fetch record by field other than id

Time:08-03

I am using Laravel to fetch records from the database for which I have created an apiResource controller. I have setup the following code inside routes.

Route::apiResource('/MyController',MyController::class)->middleware('auth:api');

In MyController.php my code to display a specific data is:

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\ContentType  $contentType
     * @return \Illuminate\Http\Response
     */
    public function show(MyModel $Model)
    {
        // show content type info
        return response([
            'data' => new MyControllerResource($Model)
        ],200);
    }

I get the data when I place an api call like this:

http://localhost:8000/api/MyController/1

What I want is a record getting fetched by passing other field value instead of id in the route. For example.

http://localhost:8000/api/MyController/mypost

Any idea how can I achieve this?

CodePudding user response:

The route key name defaults to id for all models. You will want to update this to name or whatever field "mypost" is by adding a getRouteKeyName() method.

<?php

namespace App;

...

class Post extends Model
{
    public function getRouteKeyName()
    {
        return 'name';
    }

    ...
}

CodePudding user response:

You are using route model binding. And in laravel its default behaviour is to find model with id and return collection. It will not search for any other field. Of course you can change this behaviour but it can only search data by one field. To change this behaviour use getRouteKeyName method in model like:

public function getRouteKeyName()
{
    return 'another_field_in_my_table';
}

You can also use explicit binding like:

Route::bind('MyController', function($value) {
   return \App\MyModel::where('id', $value)->orWhere('another_field_in_my_table', $value)->first();
});

To learn more about explicit binding check docs.

CodePudding user response:

You'll have to define route separately. You can group the routes by controller and middleware though. And once done, then, Inside your route, you need to change to this:

Route::get('/show/{post:columnName}', [ MyController::class, 'show' ])->middleware('auth:api');

Now your data will be fetched on the basis of your column name defined in the route.

  • Related