Reputation: 82
So, I was struggling to make this schema work (total newbie with laravel, by the way...) I have a 'photos' table and an audio 'tracks' table, and I want to be able to do something like this:
Track model:
// Get the photo associated with this track.
public function cover_art() {
return $this->hasOne('App\Photo');
}
Photo model:
// Get all the tracks associated with this photo.
public function tracks() {
return $this->belongsToMany('App\Track');
}
What's the best solution to represent this relationship (an audio track can have only one photo, and a photo can belong to multiple tracks)?
Well, finally I set up everything and I get the expected errors:
Photos table:
Schema::create('photos', function (Blueprint $table) {
$table->increments('id');
$table->string('path');
$table->string('filename');
$table->string('original_filename');
$table->boolean('is_cover')->default(false);
$table->string('title');
$table->string('slug')->unique();
$table->string('caption')->nullable();
$table->timestamps();
});
Tracks table:
Schema::create('tracks', function (Blueprint $table) {
$table->increments('id');
$table->integer('photo_id')->unsigned()->nullable();
$table->string('path');
$table->string('filename');
$table->string('original_filename');
$table->string('title');
$table->string('slug')->unique();
$table->string('caption')->nullable();
$table->timestamps();
$table->foreign('photo_id')->references('id')->on('photos')->onDelete('set null');
});
So now, when for example I call the appropriate methods in my views or in my controllers I get these errors:
@foreach($tracks as $track)
{{ $track->cover_art }}
@endforeach
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'photos.track_id' in 'where clause' (SQL: select * from photos
where photos
.track_id
= 1 and photos
.track_id
is not null limit 1)
@foreach($photos as $photo)
{{ $photo->tracks }}
@endforeach
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'iagomarta.photo_track' doesn't exist (SQL: select tracks
.*, photo_track
.photo_id
as pivot_photo_id
, photo_track
.track_id
as pivot_track_id
from tracks
inner join photo_track
on tracks
.id
= photo_track
.track_id
where photo_track
.photo_id
= 1)
Any suggestions?
Upvotes: 1
Views: 5030
Reputation: 149
Maybe it's just the typo as shown below :
create_table_tracks_migration :
Schema::create('tracks', function (Blueprint $table) {
$table->increments('id');
$table->integer('photo_id')->unsigned();
$table->string('path');
$table->string('filename');
$table->string('original_filename');
$table->string('title');
$table->string('slug')->unique();
$table->string('caption')->nullable();
$table->timestamps();
});
Schema::table('tracks', function(Blueprint $table)
{
$table->foreign('photo_id')
->references('id')
->on('photos')
->onDelete('cascade');
});
It's generally best practice to set the foreign key reference this way as I've ran into some issues myself by not doing that.
And on a side note I really don't like creating nullable foreign keys as it can create a huge mess.
Also what looks weird is that error :
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'photos.track_id' in 'where clause' (SQL: select * from photos where photos.track_id = 1 and photos.track_id is not null limit 1)
And you shouldn't have a track_id column on your photo table anyway.
In addition to that you could try to set a belongsTo(App\Photo) relationship instead of a hasOne. It would work since a track can only have one photo. Also you don't need a pivot table since it's a one to many relationship and not a many to many relationship.
Upvotes: 1
Reputation: 5942
// Track Model
public function cover_art() {
return $this->belongsTo('App\Photo');
}
// Photo Model
public function tracks() {
return $this->hasMany('App\Track');
}
Think of it like this - the 'cover art'/'photo' is sitting in place of the album, so the 'album' (photo) has many tracks, and all of the tracks belong to one album.
Upvotes: 0