Laravel 如何创建数据透视表?

Posted

技术标签:

【中文标题】Laravel 如何创建数据透视表?【英文标题】:How is a pivot table created by Laravel? 【发布时间】:2013-03-27 03:41:40 【问题描述】:

在 Laravel 4 中,当使用 the 4.2 docs 中描述的多对多关系时,我如何才能真正让 Laravel 为我创建数据透视表?

我是否需要在我的迁移中为所涉及的两个模型添加一些内容?我需要手动为数据透视表创建迁移吗?或者 Laravel 是如何知道创建数据透视表的?

到目前为止,我所做的只是将belongsToMany 信息添加到两个各自的模型中,即

class User extends Eloquent 

    public function roles()
    
         return $this->belongsToMany('Role');
     
 

但是,这不会触发数据透视表的创建。我错过了哪一步?

【问题讨论】:

【参考方案1】:

最新的 Laravel 版本:

composer require --dev laracasts/generators

php artisan make:migration:pivot table1 table2

【讨论】:

【参考方案2】:

除了以上所有答案

数据透视表不需要 AI 索引。它由其 touple (key1,key2) 唯一定义。 主键应该是组合(key1,key2)。好处是 touples 是唯一的,并且所有查询都得到了最佳优化。

所以这里有一个真实的例子:

Schema::create('bill_user', function (Blueprint $table) 
    // unsigned is needed for foreign key
    $table->integer('user_id')->unsigned();
    $table->integer('bill_id')->unsigned();

    $table->primary(['user_id', 'bill_id']);

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

    $table->foreign(bill_id')
        ->references('id')->on('bills')
        ->onDelete('cascade');
);

【讨论】:

【参考方案3】:
    创建新的迁移:
php artisan make:migration create_alpha_beta_table --create=alpha_beta
    在新创建的迁移中:
public function up() 
    Schema::create('alpha_beta', function(Blueprint $table) 
            $table->increments('id');
            $table->unsignedBigInteger('alpha_id');
            $table->unsignedBigInteger('beta_id');
            // foreign keys
            $table->foreign('alpha_id')->references('id')->on('alphas');
            $table->foreign('beta_id')->references('id')->on('betas');
     );

【讨论】:

【参考方案4】:

看起来好像确实需要手动创建数据透视表(即 Laravel 不会自动执行此操作)。操作方法如下:

1.) 创建一个新的迁移,使用 singular 表名以 字母 顺序(默认):

php artisan make:migration create_alpha_beta_table --create --table=alpha_beta

2.) 在新创建的迁移中,将 up 函数更改为:

public function up()

    Schema::create('alpha_beta', function(Blueprint $table)
    
        $table->increments('id');
        $table->integer('alpha_id');
        $table->integer('beta_id');
    );

3.) 如果需要,添加外键约束。 (我还没到那一步)。


现在要播种 alpha 表,使用 beta 中的键,您可以在 AlphaTableSeeder 中执行以下操作:

public function run()

    DB::table('alpha')->delete();

    Alpha::create( array( 
        'all'           =>  'all',
        'your'          =>  'your',
        'stuff'         =>  'stuff',
    ) )->beta()->attach( $idOfYourBeta );

【讨论】:

如果您在种子尝试运行该 model()->attach(/... 方法时收到“调用未定义方法...”,请记住为两者创建一个模型表,其中一个是属于的。例如​​,对于这个例子:在 models/Alpha.php 中,您将包括: public function beta() return $this->belongsToMany('Beta'); 我认为第一步应该是:php artisan migrate:make create_alpha_beta_table --create=alpha_beta 第一个 id 字段是否必要? 对于中间数据透视表,不应该有主键。 删除 id,添加外键,在大多数情况下,您还需要一个涵盖两个 FK 的 唯一 索引。【参考方案5】:

对于多对多关系,您可以像这样手动创建数据库的迁移文件:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateAccountTagTable extends Migration


    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    
        Schema::create('account_tag', function (Blueprint $table) 
            // $table->timestamps(); // not required
            // $table->softDeletes(); // not required

            $table->integer('account_id')->unsigned();
            $table->foreign('account_id')->references('id')->on('accounts');

            $table->integer('tag_id')->unsigned()->nullable();
            $table->foreign('tag_id')->references('id')->on('tags');
        );
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::drop('account_tag');
    

注意:如果数据透视表上有timestamps,则必须在两端的关系上设置withTimestamps,如下所示:

return $this->belongsToMany(\Mega\Modules\Account\Models\Tag::class)->withTimestamps();

.

return $this->belongsToMany(\Mega\Modules\Account\Models\Account::class)->withTimestamps();

【讨论】:

【参考方案6】:

我使用 Jeffrey Way 的 Laravel-4-Generators 或 Laravel-5-Generators-Extended。

那么你可以使用这个工匠命令:

php artisan generate:pivot table_one table_two

【讨论】:

这也会创建外键约束。 对于 Laravel-5-Generators-Extended,命令是 make:migration:pivot 而不再是 generate:pivot(就像在 Laravel-4-Generators 中一样)。【参考方案7】:

为了扩展 Ben 的答案(我试图对其进行编辑,但评论者说它添加了太多):

要添加外键约束,请确保 alpha id 是无符号的,alpha_id 在数据透视表中也是无符号的。此迁移将在 Ben 的答案中的 (2) 之后运行,因为它会更改当时创建的表。

public function up()

    Schema::table('alpha_beta', function(Blueprint $table)
    
        $table->foreign('alpha_id')->references('id')->on('alpha');
        $table->foreign('beta_id')->references('id')->on('beta');
    );

【讨论】:

谁对 1.5 岁的答案投了反对票。下一次,评论更正。 你想添加一个 onDelete('cascade'); ? $table->foreignId('alpha_id')->constrained();$table->foreignId('alpha_id') 反之亦然,现在可能是更好的方法。

以上是关于Laravel 如何创建数据透视表?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过laravel创建数据透视表

将数据添加到 Laravel 数据透视表

Laravel:如何使用数据透视表获取记录?

如何在 laravel 中使用数据透视表中的 3 个关系创建关系?

laravel:更新或创建(更新插入)数据透视表

laravel 检索值匹配数据透视表的所有用户