How is a pivot table created by Laravel?

66,932

Solution 1

It appears as though the pivot table does need to be created manually (i.e. Laravel does not do this automatically). Here's how to do it:

1.) Create a new migration, using singular table names in alphabetical order (default):

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

2.) Inside the newly created migration, change the up function to:

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

3.) Add the foreign key constraints, if desired. (I haven't gotten to that bit, yet).


Now to seed, say, the alpha table, using keys from beta, you can do the following in your AlphaTableSeeder:

public function run()
{
    DB::table('alpha')->delete();

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

Solution 2

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 3

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 4

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 5

  1. Create new migration:
php artisan make:migration create_alpha_beta_table --create=alpha_beta
  1. 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');
     });
}
Share:
66,932
Ben
Author by

Ben

I have just finished a 4-year degree in Physics & Computer Science, and now I am looking to get more into programming. I have been doing Web-Development for seemingly forever. You can talk to me in HTML & CSS, and I also know one thing or another about JS, jQuery, PHP and MySQL. Currently, I am interested in simple 2D game development. I use C++, SDL and OpenGL.

Updated on November 05, 2021

Comments

  • Ben
    Ben over 2 years

    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?

  • sersun
    sersun over 9 years
    If you are getting 'call to undefined method..." when your seed tries to run that {model}()->attach(/... method, remember to created a model for both tablese, with a belongstomany in one of them. Eg, for this example: In models/Alpha.php you would include: public function beta() { return $this->belongsToMany('Beta'); }
  • dan-klasson
    dan-klasson over 9 years
    This creates the foreign key constraints as well.
  • Adamski
    Adamski over 9 years
    I think step 1 should be: php artisan migrate:make create_alpha_beta_table --create=alpha_beta
  • Afzal N
    Afzal N over 9 years
    Whoever downvoted on a 1.5 year old answer. Next time, comment for correction.
  • Jon
    Jon over 8 years
    For Laravel-5-Generators-Extended, the command is make:migration:pivot and no longer generate:pivot (as it was in Laravel-4-Generators).
  • Miguel Stevens
    Miguel Stevens over 7 years
    is that first id field necessary?
  • Khan Shahrukh
    Khan Shahrukh over 6 years
    would you like to add an onDelete('cascade'); ?
  • Tharaka Dilshan
    Tharaka Dilshan about 5 years
    for intermediate pivot tables, there should't be a primary key.
  • okdewit
    okdewit almost 5 years
    Drop the id, add foreign keys, and in most cases you also want a unique index covering both FKs.
  • Adam
    Adam about 3 years
    @TharakaDilshan I agree, no AI primary key is needed. However, the touple [alpha_id,beta_id] should be the primary key, or at least indexed! Otherwise you query spped will slow downa lot
  • Salman Malik
    Salman Malik over 2 years
    $table->foreignId('alpha_id')->constrained(); or $table->foreignId('alpha_id') and vice versa can be a better approach now.