Laravel:如何从两个父母那里获取嵌套关系

问题描述 投票:0回答:1

我无法清楚地表达我的 Laravel 问题,所以请耐心等待我尝试解释我的问题。

我正在尝试制作一个网络界面,用户可以在其中创建页面组件的一个或多个副本(例如英雄横幅或弹出模式)。这些组件已由开发人员预先定义。我有以下表结构:

  • components
    表是最高级别的表。它包含独特组件的蓝图
  • 每个组件都有不同数量的不同属性,因此这些属性存储在
    component_properties
    表中
  • 最终用户能够创建每个组件的多个实例。这些保存在
    component_instances
    表中
  • 最终用户随后可以为 component_properties 表中定义的每个属性输入值。

我想做的是从我的控制器返回以下 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 的核心方法,但没有找到。我还尝试过将每个表作为单独的变量并在我的控制器中手动合并它们,但这似乎对性能要求很高,而且我仍然没有完全得到我需要的东西。

谢谢

laravel relationship
1个回答
0
投票

基本上,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 中的属性关系以获得所需的值。

© www.soinside.com 2019 - 2024. All rights reserved.