foreign key not recognised in laravel 4.2

125 views Asked by At

According to Dayle Rees

All foreign key columns follow a similar naming convention. The singular form of the related model appended with _id.

Consider this migration:

class CreateTables extends Migration {
// ...
    public function up()
    {
    Schema::create('artists', function($table) {
        $table->increments('id');
        $table->string('name',64);
        $table->timestamps();
    });
    Schema::create('albums', function($table) {
        $table->increments('id');
        $table->string('name',64);
        $table->integer('artist_id')->unsigned();
        $table->foreign('artist_id')->references('id')->on('artists');
        $table->timestamps();
    });
}

Here are my eloquent models:

<?php
// Artist model
class Artist extends Eloquent {
    public function albums() {
        return $this->hasMany('Album');
    }
}

<?php
// Album model
class Album extends Eloquent {
    public function artists() {
        return $this->belongsTo('Artist');
    }
}

I used them like this:

Route::get('/', function() {
    $artist = new Artist;
    $artist->name = "Morbid Angel";
    $artist->save();
    $album = new Album;
    $album->name = "Altars of Madness";
    $album->artists()->associate($artist);
    $album->save();
    return View::make('hello');
});

This does not seem to work, according to the logs:

[2015-06-09 06:01:12] production.ERROR: exception 'PDOException' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'artists_id' in 'field list''

But I did not create a artists_id. What does this mean? Shouldn't laravel find artist_id because it should be singular followed by _id?

2

There are 2 answers

9
chanafdo On BEST ANSWER

This was your problem. You have named your relation artists, but it should be artist. That's why it was looking for a column named artists_id.

You should define your relations as follow as it looks to me it is a One to Many.

In your Artists Model

public function albums()
{
    return $this->hasMany('Album');
}

In your Albums Model

public function artist()
{
    return $this->belongsTo('Artist');
}

Then try your code.

Route::get('/', function() {
    $artist = new Artist;
    $artist->name = "Morbid Angel";
    $artist->save();

    $album = new Album;
    $album->name = "Altars of Madness";

    $artist->albums()->save($album);

    return View::make('hello');
});
1
Abhishek Patel On

In your artist model try return $this->hasMany('Album', 'artist_id');