我无法清楚地表达我的 Laravel 问题,所以请耐心等待我尝试解释我的问题。
我正在尝试制作一个网络界面,用户可以在其中创建页面组件的一个或多个副本(例如英雄横幅或弹出模式)。这些组件已由开发人员预先定义。我有以下表结构:
components
表是最高级别的表。它包含独特组件的蓝图component_properties
表中component_instances
表中我想做的是从我的控制器返回以下 JSON 结构
components
component_instances
component properties
component_instance_values
例如:
{
'component': {
'id': 1,
'name': 'sample component',
'instances': [
{
'id': 1,
'properties': [
{
'id': 1,
'name': 'property 1',
'values': {
'id': 1,
'value': 'value 1',
}
]
}
]
}
}
我遇到的问题是组件实例和组件属性之间没有直接关系,因此这种结构似乎无法实现。我可以得到
components > instances > values > property
,并且在大多数情况下,这是可以接受的。但是当一个实例第一次创建时,它没有任何值。因此,我无法访问 component_properties。
我能得到我需要的结构吗?我尝试过寻找 Laravel 的核心方法,但没有找到。我还尝试过将每个表作为单独的变量并在我的控制器中手动合并它们,但这似乎对性能要求很高,而且我仍然没有完全得到我需要的东西。
谢谢
基本上,component_instance_values 是 component_instances 和 component_properties 的数据透视表,因此在 instance_values 中添加任何值之前不可能获取属性。您可以为此实例创建一个单独的数据透视表并向其附加值,这样如果尚未添加值,您仍然可以获得属性。
要获得所需的结构,您可以使用以下代码。 定义你们的关系
class Component extends Model
{
public function instances()
{
return $this->hasMany(ComponentInstance::class);
}
}
class ComponentInstance extends Model
{
public function component()
{
return $this->belongsTo(Component::class);
}
public function properties()
{
return $this->belongsToMany(ComponentProperty::class, 'component_instance_values', 'component_instance_id', 'component_property_id');
}
}
class ComponentProperty extends Model
{
public function values()
{
return $this->hasMany(ComponentInstanceValue::class);
}
}
您可以在控制器中使用如下所示的内容来获取所需的 JSON 格式
$components = Component::with(['instances.properties' => function ($query) {
$query->with('values');
}])->get();
注意:上面的代码适用于当前表的结构,如果您添加另一个数据透视表,您可以更新 ComponentInstance 中的属性关系以获得所需的值。