【问题标题】:database modeling: null foreign keys by entity type数据库建模:按实体类型的空外键
【发布时间】:2021-02-05 06:56:20
【问题描述】:

我需要一些帮助来设计我的数据库关系。 我有这些表:文档、公司、个人和用户。文档可以是内部的或外部的。

  • 如果是外部的,可以由公司或个人签名。
  • 如果是内部的,则必须由用户签名。

在任何情况下,文档都是由单个实体(公司、个人或用户)签署的。我正在考虑通过以下方式创建文档表:

documents
----------
id_document
...
type
id_user
id_company
id_indiv

其中type可以是0:内部,1:外部,id_userid_companyid_indiv是各个表的外键,可以为空。这个逻辑可以吗?有人可以建议我一个更好的主意吗?

【问题讨论】:

    标签: database laravel oop relational-database relationship


    【解决方案1】:

    Laravel 的 Eloquent ORM 提供了 Polymorphic 关系来处理这类问题。

    更具体地说,您可以放置​​两个字段; documentable_typedocumentable_id 在您的 document 表中。然后将这些关系方法添加到每个模型中;

    class Document extends Model
    {
        /**
         * Get the owning imageable model.
         */
        public function signer()
        {
            return $this->morphTo();
        }
    }
    
    class User extends Model
    {
        /**
         * Get the documents signed by this user.
         */
        public function documents()
        {
            return $this->morphMany('App\Models\Document', 'documentable');
        }
    }
    
    class Company extends Model
    {
        /**
         * Get the documents signed by this company.
         */
        public function documents()
        {
            return $this->morphMany('App\Models\Document', 'documentable');
        }
    }
    
    class Individual extends Model
    {
        /**
         * Get the documents signed by this individual.
         */
        public function documents()
        {
            return $this->morphMany('App\Models\Document', 'documentable');
        }
    }
    

    那么就可以使用下面的sn-ps;

    $document->signer; // This returns either user or company or individual
    $company->documents; // This returns a collection of document models which is signed by this company
    $individual->documents;
    $user->documents;
    

    更多详情,请查看此链接; https://laravel.com/docs/8.x/eloquent-relationships#polymorphic-relationships

    【讨论】:

    • 我真的很喜欢你的回答。但我有一个疑问。公司,个人用户是旧表,我无法修改。例如,individal 有两列:first_name,last name,company 有:bussines_name,user 有一个名为:names 的列。如何获取包含歌手姓名的文件列表。 class Individual: public function name() { return $this->first_name . ' ' . $this->last_name; } class Company: public function name() { return $this->bussines_name; } 所以我可以做 $document->signer->name();对吗?
    • $document->signer 的类型因上下文而异。正如我在回答中提到的,它既不能是 User 模型,也不能是 Company 模型或 Individual 模型。因此,最好为每个模型添加名为 name() 的常用方法。
    • 或者也定义自定义访问器(例如getNameAttribute)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多