50

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

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

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

class User extends Eloquent 
{
    public function roles()
    {
         return $this->belongsToMany('Role');
     }
 }

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

4

7 回答 7

71

看起来好像确实需要手动创建数据透视表(即 Laravel 不会自动执行此操作)。这是如何做到的:

1.) 创建一个新的迁移,使用按字母顺序排列的单数表名(默认):

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 );
}
于 2013-04-05T12:30:27.407 回答
43

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

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

php artisan generate:pivot table_one table_two
于 2014-02-15T16:59:21.990 回答
26

为了扩展本的答案(我试图编辑它,但评论家说它添加了太多):

要添加外键约束,请确保 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');
    });
}
于 2013-06-03T06:22:05.707 回答
12

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

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();
于 2016-04-07T07:08:19.520 回答
11
  1. 创建新的迁移:
php artisan make:migration create_alpha_beta_table --create=alpha_beta
  1. 在新创建的迁移中:
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');
     });
}
于 2019-10-24T11:06:02.607 回答
3

除了以上所有答案

  • 数据透视表不需要 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');
});
于 2021-02-27T08:36:30.650 回答
3

对于最新的 Laravel 版本:

composer require --dev laracasts/generators

php artisan make:migration:pivot table1 table2
于 2021-11-04T17:23:55.233 回答