我正在使用Laravel和Angular技术构建一个CRUD。然而,由于我是Laravel技术的新手,我无法在两个实体之间建立关系。我有Group实体和Subgroup实体。一个组只有它的id和名字作为属性。子组有其id、名称和组id。
我想知道如何在组和子组之间建立关系。我想在子组记录中存储组的id,但是在使用HTTP谓词执行查询时,我希望返回group对象而不是其id,以便我可以在前端操作该对象。
模型组:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Group extends Model
{
use HasFactory;
protected $fillable = [
'name'
];
protected $table = 'groups';
}
集团资源:
<?php
namespace AppHttpResources;
use IlluminateHttpResourcesJsonJsonResource;
class GroupResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param IlluminateHttpRequest $request
* @return array|IlluminateContractsSupportArrayable|JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
组迁移:
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('groups', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('groups');
}
};
子群资源:
<?php
namespace AppHttpResources;
use IlluminateHttpResourcesJsonJsonResource;
class SubgroupResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param IlluminateHttpRequest $request
* @return array|IlluminateContractsSupportArrayable|JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'group_id' => $this->group_id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
子群模型:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Subgroup extends Model
{
use HasFactory;
protected $fillable = [
'group_id'
];
protected $table = 'subgroups';
}
子群迁移:
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('subgroups', function (Blueprint $table) {
$table->increments('id');
$table->foreignIdFor(Group::class);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('subgroups');
}
};
子群控制器:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppModelsSubgroup;
class SubgroupController extends Controller
{
/**
* Display a listing of the resource.
*
* @return IlluminateHttpResponse
*/
public function index()
{
return Subgroup::all();
}
/**
* Store a newly created resource in storage.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(Request $request)
{
return Subgroup::create($request->all());
}
/**
* Display the specified resource.
*
* @param int $id
* @return IlluminateHttpResponse
*/
public function show($id)
{
return Subgroup::find($id);
}
/**
* Update the specified resource in storage.
*
* @param IlluminateHttpRequest $request
* @param int $id
* @return IlluminateHttpResponse
*/
public function update(Request $request, $id)
{
if (Subgroup::where('id', $id)->exists()) {
$subgroup = Subgroup::find($id);
$subgroup->group_id = $request->group_id;
$subgroup->save();
return response()->json([
"message" => "Success"
], 200);
} else {
return response()->json([
"message" => "Error"
], 404);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return IlluminateHttpResponse
*/
public function destroy($id)
{
if (Subgroup::where('id', $id)->exists()) {
$subgroup = Subgroup::find($id);
$subgroup->delete();
return response()->json([
"message" => "Successfully deleted"
], 202);
} else {
return response()->json([
"message" => "Not Found"
], 404);
}
}
}
我想知道我是否在正确的道路上建立表之间的关系。此外,检索子组时,我希望group_id字段不返回id,但组对象,我怎么能做到这一点?
你必须使用Relationships,它在文档中有一整节…
所以,我认为你想要一个1-to-N
(一对多),所以一个Group
可以有多个Subgroups
。
如果是这种情况,你应该有:
组模型namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Group extends Model
{
use HasFactory;
protected $fillable = [
'name'
];
public function subgroups()
{
return $this->hasMany(Subgroup::class);
}
}
子群
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Subgroup extends Model
{
use HasFactory;
protected $fillable = [
'group_id'
];
public function group()
{
return $this->belongsTo(Group::class);
}
}
看到我已经从两者中删除了$table
,因为框架将能够定义与您在那里定义的相同的名称。
现在,如果你想在你的Resource
上返回一个name
而不是group_id
,你应该这样做(在应用之前的更改之后):
namespace AppHttpResources;
use IlluminateHttpResourcesJsonJsonResource;
class SubgroupResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param IlluminateHttpRequest $request
* @return array|IlluminateContractsSupportArrayable|JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'group_name' => $this->group->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
如果您阅读文档,您将看到,在定义关系(例如,group
方法)之后,您可以使用$model->group
,如果找到,它将返回相关的Group
模型,否则将返回null
。你也可以使用$model->group()
,它将返回一个Builder
,这样你就可以在该资源上做一些事情(使用构建器,而不是模型类)。
在您的特定情况下,您可以直接返回对象,如您所愿,通过以下操作:
namespace AppHttpResources;
use IlluminateHttpResourcesJsonJsonResource;
class SubgroupResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param IlluminateHttpRequest $request
* @return array|IlluminateContractsSupportArrayable|JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'group' => $this->group,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}