为了账号安全,请及时绑定邮箱和手机立即绑定

如何为具有组合主键的表创建 CRUD API

如何为具有组合主键的表创建 CRUD API

PHP
繁华开满天机 2022-06-17 17:07:59
我有一个提供 CRUD API 的 Laravel 应用程序。有一个包含主键的表,我在模型和迁移文件中介绍了键:protected $primaryKey = ['personel_id', 'valid_for_quarter'];我也这样定义了它的路线:Route::middleware('auth:api')->group( function () { Route::apiResources([    'peopleDatas' => 'API\PeopleDataController' ]);});以及包含show如下方法的控制器类:public function show(PeopleData $peopleData){    dd($peopleData);}  现在的问题是:1、当对象有多个主键的情况下,访问show方法的url是什么?请注意,我没有自己明确定义路由 url,我想使用Route::apiResources方法。可能吗?这是路线列表:|        | GET|HEAD  | api/peopleDatas                         | peopleDatas.index                 | App\Http\Controllers\API\PeopleDataController@index                       | api,auth:api ||        | POST      | api/peopleDatas                         | peopleDatas.store                 | App\Http\Controllers\API\PeopleDataController@store                       | api,auth:api ||        | GET|HEAD  | api/peopleDatas/{peopleData}            | peopleDatas.show                  | App\Http\Controllers\API\PeopleDataController@show                        | api,auth:api ||        | DELETE    | api/peopleDatas/{peopleData}            | peopleDatas.destroy               | App\Http\Controllers\API\PeopleDataController@destroy                     | api,auth:api ||        | PUT|PATCH | api/peopleDatas/{peopleData}            | peopleDatas.update                | App\Http\Controllers\API\PeopleDataController@update                      | api,auth:api |另一方面,在这种情况下我应该明确定义网址吗?例如/api/peopleDatas/{key1}/{key2},或者有任何适用于 Laravel 的标准方法吗?2.如果对象有多个主键Eloquent,Laravel 路由模型绑定是否可以处理它并从数据库中获取项目,或者我需要从用户那里获取 id 并将find函数应用于我的模型?3.如果 Laravel 默认不处理它,是否可以重写一些函数来告诉 Laravel 如何从数据库中获取项目以防万一Route Model Binding?
查看完整描述

1 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

是否有理由不能将单个唯一值(例如自动增量 ID)作为主键,然后将两个附加索引作为唯一复合索引?


这将解决您的路由参数问题,因为您只有一个主键:


/api/peopleDatas/{id}


您的迁移将包括唯一复合索引的规范:


$table->unique(['personel_id', 'valid_for_quarter']);

这样,您的组合列保持唯一性,而您的路线被简化为单个 ID,并且您的关系也可以使用单个 ID。这将提高性能并简化代码。


或者,如果您绝对必须有一个复合主键,您可以这样做。您的迁移需要:


$table->primary(['personel_id', 'valid_for_quarter']);

您的模型需要为保存查询设置键(请参阅链接) https://blog.maqe.com/solved-eloquent-doesnt-support-composite-primary-keys-62b740120f


protected function setKeysForSaveQuery(Builder $query)

{

    $query

        ->where('personel_id', '=', $this->getAttribute('personel_id'))

        ->where('valid_for_quarter', '=', $this->getAttribute('valid_for_quarter'));


    return $query;

}

路由绑定的最佳解决方案是使用显式路由模型绑定(请参阅文档链接),您的参数是两个键的分隔组合:


/api/peopleDatas/{people_data}人员数据 =1_3例如


https://laravel.com/docs/5.8/routing#explicit-binding


在您的路线服务提供商中,您需要指定解析逻辑,如下所示:


public function boot()

{

    parent::boot();


    Route::bind('people_data', function ($value) {

        return App\PeopleData::where('personal_id', explode('_', $value)[0])

            ->where('valid_for_quarter',  explode('_', $value)[1])

            ->first() ?? abort(404);

    });

}


查看完整回答
反对 回复 2022-06-17
  • 1 回答
  • 0 关注
  • 156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信