2
votes

I'm trying to build some relationships in Laravel, i'm a little confused about relationships and migrations. Here is a simple example of what i'm doing:

Users -> has_many -> Cats

So my Users migration file has a relationship to Cats like so:

$table->foreign('cats_id')->references('id')->on('cats')

But when I run my migration, I get:

Error: relation cats does not exist...

Do I need to build the Cats table before the Users table?

Do I also need to specify the foreign relation between the two, or if the models contain "hasMany" and "belongsTo" wouldn't Laravel build those relationships automatically on migration?

Do I actually need migrations?

4
You will need to create both tables, then the models, then seed the tables.Ohgodwhy

4 Answers

5
votes

You can't reference a table that not exists. It has nothing to do with Laravel or Eloquent, it's (My)SQL thing.

First create the parent table users, then the child table cats referencing the first:

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

this is how User hasMany Cat would look like. cats table has foreign key referencing users table, not the other way around like you tried.

1
votes

You need to set the foreign key to the table where the 'many' are.

$table->foreign('id')->references('cats_id')->on('Users')

You need to make sure that

  • Table 'Users' exists before you create table Cats (Or any other table that is referenced)
  • Column 'id' exists before you create the foreign key. (Or any other column that is referenced)

A quite bulletproof solution for me is to setup the tables with a first migration eg

    public function up()
{
    Schema::create('users', function(Blueprint $table)
    {

        $table->increments('id');
        $table->timestamps();
        $table->string('cats_id');

    });


    //and 


    Schema::create('cats', function(Blueprint $table)
    {

        $table->increments('id');
        $table->timestamps();
        $table->string('cat_name');

    });
}

in one migration file and then I create another migration file that runs in the end and creates all the foreign keys for all migrations that were running before:

public function up()
    {
        Schema::table('cats', function(Blueprint $table)
        {
            $table->foreign('id')->references('cats_id')->on('users');
        });
    }

You can also choose what should happen to your cats table on update or delete of a user by adding eg

->onUpdate('CASCADE')->onDelete('CASCADE');

to the $table->... line

0
votes

You will have to run the migration for cats table and create that table before you can associate it with users table.

Foreign key relation will be helpful when you are required to do cascade delete or update. Also an insert like the following will be easier for you with the cats relationship set.

$user = User::find(1);

$cats = array(
    new Cat(array('name' => 'Kitty')),
    new Cat(array('name' => 'Lily')),
);

$user->cats()->save($cats);
-1
votes

When specifying a relationship on User Model the Cat model also needs to exist.

In migration

Users

$table->foreign('cats_id')->references('id')->on('cats');

Cats

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

Now you force integrity on database level.

Migrate

run the migration using php artisan migrate

Next step is to add the integrity on you Model

Model

User.php

public function cats()
{
    return $this->hasMany('Cats');
}

Cat.php

public function user()
{
    return $this->belongsTo('User');
}