'How is a pivot table created by Laravel?
In Laravel 4, when working with many-to-many relationships as described in the 4.2 docs, how can I actually get Laravel to create the pivot table for me?
Do I need to add something in my migrations for the two models that are involved? Do I need to manually create a migration for the pivot table? Or how does Laravel know to create the pivot table?
All I've done so far is add the belongsToMany information to the two respective models, i.e.
class User extends Eloquent
{
public function roles()
{
return $this->belongsToMany('Role');
}
}
However, that does not trigger creation of the pivot table. What step am I missing?
Solution 1:[1]
I use Jeffrey Way's Laravel-4-Generators or Laravel-5-Generators-Extended.
then you can just use this artisan command:
php artisan generate:pivot table_one table_two
Solution 2:[2]
To expand on Ben's answer (I tried to edit it but reviewers said it added too much):
To add the foreign key constraints, make sure if alpha id is unsigned, alpha_id is also unsigned in the pivot table. This migration would run after (2) in Ben's answer since it alters the table created then.
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');
});
}
Solution 3:[3]
For Many to Many relationships you can create the Migration file of the Database manually like this:
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');
}
}
Note: in case you have timestamps on the pivot table you must set withTimestamps on the relationship of both ends like this:
return $this->belongsToMany(\Mega\Modules\Account\Models\Tag::class)->withTimestamps();
.
return $this->belongsToMany(\Mega\Modules\Account\Models\Account::class)->withTimestamps();
Solution 4:[4]
- Create new migration:
php artisan make:migration create_alpha_beta_table --create=alpha_beta
- Inside the newly created migration:
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');
});
}
Solution 5:[5]
for the latest Laravel's versions:
composer require --dev laracasts/generators
php artisan make:migration:pivot table1 table2
Solution 6:[6]
In addition to all the above answers
- There is no need to have an AI index for a pivot table. Its uniquely defined by its touple (key1,key2).
- The primary key should be the composition (key1,key2). The benefits are that the touples are unique and all queries are best optimized.
So here comes a real life example:
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');
});
Solution 7:[7]
following the latest laravel conventions, the up method should be
public function up() {
Schema::create('country_timezone', function (Blueprint $table) {
$table->foreignId('country_id')->references('id')->on('countries');
$table->foreignId('timezone_id')->references('id')->on('timezones');
});
}
the simplest but modern way of writing pivot table migration, where the Country and Timezone are models with many-to-many relationship. And id and timestamps are not necessary to include but straightforward manner
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Geoffrey |
| Solution 2 | Afzal N |
| Solution 3 | Mahmoud Zalt |
| Solution 4 | |
| Solution 5 | |
| Solution 6 | Adam |
| Solution 7 |
