【问题标题】:Laravel relationships in migrations?迁移中的 Laravel 关系?
【发布时间】:2012-11-12 12:36:39
【问题描述】:

我知道您可以使用$this->belongs_to()$this->has_many() 等轻松定义表关系,但我不明白关系表是如何创建的;将两个表绑定在一起的表(我忘记了这个术语叫什么)。

假设我正在创建一个用户表。我希望该用户属于某个“角色”。有多个角色,每个角色可以有多个用户。我还需要为此创建一个roles 表。到目前为止,一切顺利。

但在阅读文档后,它说我应该在模型中添加$this->belongs_to(),而不是迁移本身。何时以及如何创建关系表?如果我创建rolesusers 表,并将$this->belongs_to('roles') 添加到users 模型,将$this->has_many('users') 添加到roles 模型,会自动创建中间表吗?

【问题讨论】:

  • 关于“我忘了这个词叫什么”,这些表通常被称为数据透视表、中间表或查找表,具体取决于您来自哪个数据库背景。

标签: database migration relationship laravel


【解决方案1】:

创建迁移时,您可以在表上指定外键, 即

public function up()
{
    Schema::table('roles', function(Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        //rest of fields then...
        $table->foreign('user_id')->references('id')->on('users');
    });
}

这将在角色表的 user_id 列上创建一个外键。 外键的好处是当更新或删除时,外键表会自动更新或“级联”很好的描述找到here

如 Laravel 文档中所述,您还可以使用以下语法指定更新时的级联

$table->foreign('user_id')
  ->references('id')->on('users')
  ->onDelete('cascade');

如果试图比文档更好地解释它,我会做得不好,因此请通读 Eloquent ORM 文档的 "Relationships" 部分,看看它是如何完成的。

【讨论】:

  • @Roark 你可能应该提到应该首先创建列“user_id”.. 否则你会收到类似的错误:``` [Illuminate\Database\QueryException] SQLSTATE[42703] :未定义列:7 错误:外键约束中引用的列“lang_id”不存在(SQL:alter table“op_cities”添加约束“op_cities_lang_id_foreign”外键(“lang_id”)引用“translator_languages”(“id”)) ```
  • 这里的例子:easylaravelbook.com/blog/…
  • @abbood 更新答案以显示更详细的迁移示例
  • 为什么我总是遇到只有 $table->unsignedBigInteger('user_id');有效吗?
  • @james 查看这篇文章。如果您使用的是 Laravel 5.8,这可能是原因:laraveldaily.com/…
【解决方案2】:

似乎一些最初的问题从未得到解答,即“关系表何时以及如何创建”和“中间表是否会自动创建”:

据我所知,这些表需要手动创建。所以像这样创建迁移文件:

Laravel 5

php artisan make:migration create_role_user_table

Laravel 4

php artisan migrate:make create_role_user_table

请注意,这些名称是单数的,并按字母顺序显示。

然后在迁移中类似于:

public function up()
{
    Schema::create('role_user', function($table) {
        $table->increments('id');
        $table->integer('role_id');
        $table->integer('user_id');
        $table->timestamps();
    });
}

希望对您有所帮助。我不确定数据透视表中是否需要时间戳,所以请尝试一下。

【讨论】:

  • migrate:make 不是 Laravel 5.4 的工匠,它是 php artisan make:migration
【解决方案3】:

虽然它是一个旧帖子,但我可以贡献一些更新的东西。对于 Laravel5,Jeffrey Way 开发了一个包 Laravel5 Generators-extended,它增强了 php artisan 的生成器能力,用于

  • make:migration:schema
  • make:migration:pivot
  • make:seed

对于用户和角色之间的多对多关系,您可以使用

php artisan make:migration:pivot users role

它将生成所需的迁移类。您无需为此手动编写代码。

【讨论】:

    【解决方案4】:

    据我所知,不会创建任何关系表。您需要做的是在您的users 表上有一个role_id,这样当您创建用户时,角色的ID 将被存储在那里。这将使您能够选择role_id == '1' 或任何可能的所有用户。 例如:

    $admins = User::where('role_id', '=', 1);
    

    ROLES 表中ID='1' 的记录是 admin。 因此,再次回答您的问题,没有创建关系表,而是以每个用户的 role_id 列的形式存在于您的两个表中。出于兴趣,您是否使用外键?

    如果您想要一个关系表,您可以创建一个名为 user_roles 或其他名称的表并将 role_iduser_id 存储在其中,但是我认为使用上述方法更容易,因为您可以使用所有Laravel/雄辩的善良。

    希望这会有所帮助:)

    【讨论】:

    • 感谢您的回答!我发现如果我只为每个用户存储一个角色,则不需要关系表。但是,如果每个用户都可以拥有无​​限的角色呢?那我别无选择,只能将它存储在另一个表中,对吗?那将如何运作?我知道 Laravel 可以为您自动创建和管理这些表,但我不知道它是如何、在何处或何时这样做的。
    • 那么,是通过更改迁移文件或仅在模型文件中定义关系来在数据库本身上创建关系,哪个更好?或同时使用这两种技术
    【解决方案5】:

    这个视频帮助了我。

    https://laracasts.com/series/laravel-5-fundamentals/episodes/14

    令我惊讶的是,迁移表中只有关系的一侧需要pointer_id,而不是两者。例如,如果我们有很多文章的作者,我们只添加

    $table->integer('author_id')
    

    到文章迁移,仅此而已。

    【讨论】:

      【解决方案6】:

      我知道这是一篇旧帖子,但我也有同样的问题。我在Laravel manual (5.0) 中找到了解决方案,其中描述了对于这种特殊的多对多关系,您可以手动创建表,然后以这种方式将关系类型声明到模型中:

      return $this -> belongsToMany('App\<Model>', '<table_created_manually>');
      

      或者如果您想使用特定的关联键:

      return $this -> belongsToMany('App\<Model>', '<rel_table1_table2>' '<table1>_id', '<table2>_id');
      

      希望这能有所帮助。

      【讨论】:

        猜你喜欢
        • 2018-06-21
        • 2017-01-04
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 2020-05-08
        • 2018-10-21
        • 2016-09-17
        相关资源
        最近更新 更多