在 Laravel 数据库/模型设置中用于需要不同列的关系的正确约定?

Posted

技术标签:

【中文标题】在 Laravel 数据库/模型设置中用于需要不同列的关系的正确约定?【英文标题】:Right convention to use in Laravel database/model setup for relationships that needs different column's? 【发布时间】:2021-06-12 22:48:18 【问题描述】:

好吧,让我解释一下我想要什么

我应该有多个“用户”(ID、姓名、电子邮件...),每个用户应该有多个“account_types”中的一个(ID、姓名)。

这似乎很容易设置,但棘手的部分来了。

每个“account_type”应该有不同的信息,然后我认为正确的方法是为每个“account_type”创建一个新表,其中包含每种类型所需的列,但我不确定

让我用这个例子解释一下我想要什么:

Account types:  
ID: 1, Name: Private user 
ID: 2, Name: Company user 
.... More to be added ....

私人用户所需的信息应该是:

First name, Last name

但对于公司用户来说应该是:

Company name, Company identification number

我当然可以将此信息存储在 users 表中,使它们可以为空,然后根据它的“account_type”输出所需的信息,但这似乎是错误的,因为可以为空的选项会越来越多“ account_types”被添加。此外,我需要根据“帐户类型”对我需要的信息进行硬编码,我认为这不是在这里使用的正确约定?

我应该如何在 Laravel 中进行设置? - 这里的正确约定是什么? - 如果我为每个“account_type”创建一个新表是正确的,我将如何使用它(我是否需要为每个表创建一个模型,以及如何告诉 Laravel 使用正确的模型,制作时这个用)?

编辑

在阅读了 Anurat 的评论后(感谢您将我引向正确的方向),我现在知道正确的方法是为每个帐户类型创建一个表,然后为每个表创建一个模型,然后我可以使用多态关系,但我仍然不知道它是如何工作的

我创建了以下迁移(并且每个迁移都有一个模型):

    Schema::create('account_types', function (Blueprint $table) 
        $table->id();
        $table->string('name');
        $table->timestamps();
    );

    Schema::create('private_account_infos', function (Blueprint $table) 
        $table->id();
        $table->string('first_name');
        $table->string('last_name');
        $table->timestamps();
    );

    Schema::create('firm_account_infos', function (Blueprint $table) 
        $table->id();
        $table->integer('cvr');
        $table->string('company_name');
        $table->timestamps();
    );

    Schema::create('users', function (Blueprint $table) 
        $table->id();
        $table->foreignId('account_type')->constrained()->cascadeOnDelete();
        $table->morphs('fillable');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    );

在这里,我将 $table->morphs 放在了 users 表上,但对吗? - 用户要么在firm_account_infos 或private_account_infos 中有信息,所以这就是我放在users 表中的原因,但是当我考虑它时,它应该是“account_types”,如果用户可以在firm_account_infos 或private_account_infos 中有信息,那么有什么变化我需要进行迁移以使其正确吗?

【问题讨论】:

为每个账户类型创建一个表,为每个表创建一个模型并与其他表使用多态关系laravel.com/docs/8.x/… 谢谢你的帮助!但我还是不太明白。我已经更新了我的问题,您能否详细说明需要做什么? 【参考方案1】:

我的理解是您不需要account_types 表,因为我们已经将不同类型的帐户拆分为表,即私人和公司表。 privates 中的所有记录都将具有相同的 account_type 并且对于公司中的所有记录都相同。

那么你就可以和users表建立一对一的多态关系了。

 privates ----|
              |----- users
 firms -------|

您需要添加到用户表架构

Schema::create('users', function (Blueprint $table) 
    $table->unsignedInteger('userable_id');
    $table->string('userable_type');
);

然后你在用户、私人和公司中建立关系。

// User model

public function userable()

    return $this->morphTo();


// Private, Firm model

public function user()

    return $this->morphOne(User::class, 'userable');

当你想检索相关模型时,可以

$user->userable;  // either private or firm

$private->user;
$firm->user;

【讨论】:

好吧,现在说得通了,但我的问题中没有包括的是每个 account_type 也应该有多种用途。前任。私人用户有“买家”和“卖家”作为目的,企业有“0-5”、“5-10”、“10-20”,最后是“20+”。删除该表时,如何使此目的表属于每个“account_type”? @MichaelJorgensenDK 我仍然不明白这些目的。但是您仍然可以添加 account_type 表,该表将与 privates 和 firm 表具有正常的一对多关系。 我可以让“userable_type”来自另一个表(account_types),并且只将“userable_id”和“account_type_id”存储在users表中。那么“account_type_id.userable_type”应该指向它属于哪个表? 是的,如果你的数据库设计看起来像图片,你可以这样做,但一定要阅读手册laravel.com/docs/8.x/…

以上是关于在 Laravel 数据库/模型设置中用于需要不同列的关系的正确约定?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 中的模型继承

Laravel - 使用 Auth::user() 设置模型连接

用于 Laravel Nova 中同一模型上的两个资源字段的 relatableQuery()

在 laravel 4 中使用五个模型的 Eloquent 映射表关系

是否有必要在 laravel 中为数据库操作创建模型(用于查询构建器)?

如何为Laravel中的每个会话设置不同的到期时间?