Php 我们可以打个“电话”吗;“班级关系”;在Laravel中,与“;对象级关系“;?

Php 我们可以打个“电话”吗;“班级关系”;在Laravel中,与“;对象级关系“;?,php,mysql,laravel,Php,Mysql,Laravel,考虑以下场景: 我的Laravel应用程序中有两个实体,如下所示: Post 页面 图像 视频 上述所有实体都可以有CustomFieldValues,这是另一个实体。自定义字段值表的结构如下所示: 身份证 实体id 自定义\字段\定义\ id 价值观 [时间戳字段] 所有CustomFieldValues都属于一个CustomFieldDefinition实体。其表自定义字段定义如下所示: 身份证 父实体名称 定义名称 [时间戳字段] 以下是自定义字段定义表中的一些示例数据: |

考虑以下场景:

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

  • Post
  • 页面
  • 图像
  • 视频
上述所有实体都可以有
CustomFieldValue
s,这是另一个实体。
自定义字段值表的结构如下所示:

  • 身份证
  • 实体id
  • 自定义\字段\定义\ id
  • 价值观
  • [时间戳字段]
所有
CustomFieldValue
s都属于一个
CustomFieldDefinition
实体。其表
自定义字段定义
如下所示:

  • 身份证
  • 父实体名称
  • 定义名称
  • [时间戳字段]
以下是
自定义字段定义
表中的一些示例数据:

| ID | parent_entity_name | definition_name   |
|----|--------------------|-------------------|
| 1  | Post               | AuthorTwitterUrl  |
| 2  | Page               | SeoTitle          |
| 3  | Image              | OriginalSourceUrl |
| 4  | Video              | MpaaRating        |
| 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             |
如您所见,
CustomFieldDefinition
s是额外数据的定义,我们可以存储每种类型的实体

以下是来自
自定义字段值
表的一些样本数据:

| ID | parent_entity_name | definition_name   |
|----|--------------------|-------------------|
| 1  | Post               | AuthorTwitterUrl  |
| 2  | Page               | SeoTitle          |
| 3  | Image              | OriginalSourceUrl |
| 4  | Video              | MpaaRating        |
| 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\u field\u values
表中包含的数据的一点说明:

| ID | parent_entity_name | definition_name   |
|----|--------------------|-------------------|
| 1  | Post               | AuthorTwitterUrl  |
| 2  | Page               | SeoTitle          |
| 3  | Image              | OriginalSourceUrl |
| 4  | Video              | MpaaRating        |
| 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             |
  • CustomFieldValue:1
    CustomFieldDefinition:1
    及其实体1(
    Post:1
    ,在本例中,因为
    CustomFieldDefinition:1
    Post
    相关)的值为“”
  • CustomFieldValue:2
    CustomFieldDefinition:2
    及其实体1(
    Page:1
    ,在本例中,因为
    CustomFieldDefinition:2
    Page
    相关)的值是“我的页面的SEO标题”
  • CustomFieldValue:3
    CustomFieldDefinition:3
    及其实体1(
    Image:1
    ,在本例中,因为
    CustomFieldDefinition:3
    Image
    相关)的值为“”
  • CustomFieldValue:4
    CustomFieldDefinition:4
    及其实体1(
    Video:1
    ,在本例中,因为
    CustomFieldDefinition:4
    Video
    相关)的值为“G–一般观众”
自定义字段值
表的
实体id
可以引用任何实体类,因此它不是DB级别的外键。只有结合
custom\u field\u definition\u id
我们才能找到它实际引用的实体


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

类后扩展模型{
公共函数customFieldDefinitions(){
$this->hasMany('CustomFieldDefinition');
}
}
上述操作不起作用,因为指示
CustomFieldDefinition
关系的数据点不是名为
post\u id
custom\u field\u definitions
表中的外键字段。我们必须以某种方式建立这种关系,因为
自定义字段\u定义
表中的某些记录将“Post”作为字段
父实体\u名称
的值

CustomFieldDefinition::where('parent_entity_name','=','Post');
上面的代码片段获取与
Post
相关的
CustomFieldDefinition
,但是,不可能对关系执行以下操作:

class Post extends Model
{

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

   public function customFieldDefinitions()
   {
       return $this->hasMany(
           'CustomFieldDefinition',
           'parent_entity_name',
           'entity_name'
      );
   }
}
类后扩展模型{
公共函数customFieldDefinitions(){
美元这个
->hasMany('CustomFieldDefinition')
->其中('parent_entity_name','=','Post')
;
}
}
约束起作用的地方。但是,Laravel还将当前
Post
对象的ID注入约束集中

<> >,我想做的是,不要考虑当前对象的ID,建立一个“类间关系”,而不是一个“对象级关系”。 这在Laravel下可能吗?

您可以在
Post
Page
Image
Video
CustomFieldDefinition
之间创建
一对多(多态)
关系

有关多态关系的更多信息。

您可以在
Post
Page
Image
Video
CustomFieldDefinition
之间创建
一对多(多态)
关系,而不是
hasMany()


更多关于多态关系的信息。

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

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

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;
}

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

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

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;
}

“但是Laravel也将当前Post对象的ID注入到约束集中。”-这是意料之中的。您最好的选择是定义自己的静态函数,该函数以当前帖子ID为参数。@Script47:我试图找到是否有办法使用适当的Larvel关系来实现这一点,而不是定义自己的方法,该方法将
返回CustomFieldDefinition::where('parent_entity_name','=','post')->get(),但Laravel也会注入当前Post对象的ID