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 如何创建数据透视表?的主要内容,如果未能解决你的问题,请参考以下文章