gpt4 book ai didi

php - 我们可以在 Laravel 中创建一个 "Class Level Relationship"而不是 "Object Level Relationship"吗?

转载 作者:行者123 更新时间:2023-11-29 04:32:26 27 4
gpt4 key购买 nike

考虑以下场景:

我的 Laravel 应用程序中有几个实体,如下所示:

  • 发布
  • 页面
  • 图片
  • 视频

以上所有实体都可以有CustomFieldValue,这是另一个实体。 custom_field_values表的结构如下:

  • 身份证
  • 实体编号
  • custom_field_definition_id
  • 值(value)
  • [时间戳字段]

所有 CustomFieldValue 都属于一个 CustomFieldDefinition 实体。它的表 custom_field_definitions 如下所示:

  • 身份证
  • parent_entity_name
  • 定义名称
  • [时间戳字段]

以下是 custom_field_definitions 表中的一些示例数据:

| ID | parent_entity_name | definition_name   |
|----|--------------------|-------------------|
| 1 | Post | AuthorTwitterUrl |
| 2 | Page | SeoTitle |
| 3 | Image | OriginalSourceUrl |
| 4 | Video | MpaaRating |

如您所见,CustomFieldDefinition 是额外数据的定义,我们可以存储每种类型的实体。

以下是 custom_field_values 表中的一些样本数据:

| ID | entity_id | custom_field_definition_id | value                             |
|----|-----------|----------------------------|-----------------------------------|
| 1 | 1 | 1 | https://twitter.com/StackOverflow |
| 2 | 1 | 2 | My Page's SEO Title |
| 3 | 1 | 3 | http://example.com/image.jpg |
| 4 | 1 | 4 | G – General Audiences |

关于 custom_field_values 表中包含的数据的一些描述:

  • CustomFieldValue:1:CustomFieldDefinition:1 及其实体 1 的值(Post:1,在本例中,因为 CustomFieldDefinition:1Post 相关。)是“https://twitter.com/StackOverflow”。
  • CustomFieldValue:2:CustomFieldDefinition:2 及其实体 1 的值(Page:1,在本例中,因为 CustomFieldDefinition:2Page 相关。)是“我的页面的 SEO 标题”。
  • CustomFieldValue:3:CustomFieldDefinition:3 及其实体 1 的值(Image:1,在本例中,因为 CustomFieldDefinition:3Image 相关。) 是“http://example.com/image.jpg”。
  • CustomFieldValue:4:CustomFieldDefinition:4 及其实体 1 的值(Video:1,在本例中,因为 CustomFieldDefinition:4Video 相关。)是“G – General Audiences”。

custom_field_values 表的entity_id 可以引用任何实体类,因此它不是数据库级别的外键。只有结合 custom_field_definition_id 我们才能找到它实际指代的实体。


现在,一切都很好,直到我需要将名为 customFieldDefinitions 的关系添加到任何实体(比如 Post。)。

class Post extends Model {
public function customFieldDefinitions(){
$this -> hasMany ('CustomFieldDefinition');
}
}

以上不起作用,因为指示CustomFieldDefinition 关系的数据点不是custom_field_definitions 表中名为post_id< 的外键字段。我们必须根据以下事实以某种方式建立关系:custom_field_definitions 表中的某些记录将“Post”作为字段 parent_entity_name 的值。

CustomFieldDefinition::where('parent_entity_name', '=', 'Post');

上面的代码片段获取与 Post 相关的 CustomFieldDefinition,但是,不可能对关系执行如下操作:

class Post extends Model {
public function customFieldDefinitions(){
$this
-> hasMany ('CustomFieldDefinition')
-> where ('parent_entity_name', '=', 'Post')
;
}
}

where 约束有效。但是 Laravel 还将当前 Post 对象的 ID 注入(inject)到约束集中。

所以,我想做的是,根本不考虑当前对象的 ID,而是建立“类层次关系”,而不是“对象层次关系”。

这在 Laravel 下可行吗?

最佳答案

可能有解决方法,但我不太确定。

您可以尝试做的是定义一个变异属性并将其设置为关系的本地键:

class Post extends Model
{

public function getEntityNameAttribute()
{
return 'Post';
}

public function customFieldDefinitions()
{
return $this->hasMany(
'CustomFieldDefinition',
'parent_entity_name',
'entity_name'
);
}
}

您还可以更进一步,定义一个特征,您所有具有 customFieldDefinitions 的模型都可以使用该特征。它可能看起来像:

trait HasCustomFieldDefinitionsTrait
{
public function getEntityNameAttribute()
{
return (new ReflectionClass($this))->getShortName();
}

public function customFieldDefinitions()
{
return $this->hasMany(
'CustomFieldDefinition',
'parent_entity_name',
'entity_name'
);
}
}

然后你可以在任何需要的地方使用它:

class Post extends Model
{
use HasCustomFieldDefinitionsTrait;
}

class Video extends Model
{
use HasCustomFieldDefinitionsTrait;
}

class Page extends Model
{
use HasCustomFieldDefinitionsTrait;
}

class Image extends Model
{
use HasCustomFieldDefinitionsTrait;
}

关于php - 我们可以在 Laravel 中创建一个 "Class Level Relationship"而不是 "Object Level Relationship"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57057037/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com