简体   繁体   中英

Laravel apiResource to fetch record by field other than id

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?

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 .

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';
    }

    ...
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM