I have troubleshoot all day with eager loading/n+1 issue, researched and read and watched tutorials about this issue, but haven't solved it yet. I have set up the relationships for the models, but when I passing in the data with a helper function I got this n+1 issue. I want to grab an artist name from the url site.com/Artist/songs and get all its songs and display an url like this.
site.com/$Artist/songs/$id
My artists/index.blade.php view looks like this http://i61.tinypic.com/2nqzatk.jpg I'm not sure what I'm missing here.
Thanks in advance!
My tables
songs id, title, body, slug, hits, artist_id, created_at, updated_at
artists id, name, body, created_at, updated_at
routes.php
Event::listen('illuminate.query', function($query)
{
var_dump($query);
});
...
Route::get('{artist}/songs', 'ArtistsController@index');
Route::get('{artist}/songs/{id}', ['as' => 'artist.songs.show', 'uses' => 'ArtistsController@show']);
Model: Song.php
class Song extends Eloquent {
protected $guarded = ['id'];
/**
* Setting up relationship for the artist model for easier usage
*
*/
public function artist()
{
return $this->belongsTo('Artist');
}
// Override find method
public static function find($id, $name = null)
{
$song = static::with('artist')->find($id);
// If the song is found
if ($song)
{
// If the song doesn't belong to that artist, throw an exception which will redirect to home, defined in global.php
if ($name and $song->artist->name !== $name)
{
throw new Illuminate\Database\Eloquent\ModelNotFoundException;
}
return $song;
}
// If the song is not found, throw an exception which will redirect to home, defined in global.php
else
{
throw new Illuminate\Database\Eloquent\ModelNotFoundException;
}
}
// Get songs from artist
public static function byArtist($name)
{
return Artist::byName($name)->songs;
}
}
Model Artist.php
class Artist extends Eloquent {
protected $fillable = [];
/**
* Setting up relationship with the song model for easier usage
* $artist->songs;
*/
public function songs()
{
return $this->hasMany('Song');
}
// Get artist by name
public static function byName($name)
{
return static::whereName($name)->first();
}
}
Controller: ArtistsController.php
class ArtistsController extends BaseController {
// Set default layout for this controller
protected $layout = 'layouts.master';
/**
* Display a listing of the resource.
* GET /artists
*
* @return Response
*/
public function index($name)
{
$this->data['songs'] = Song::byArtist($name);
$this->layout->content = View::make('artists.index', $this->data);
}
helpers.php
function link_to_artist_song(Song $song)
{
return link_to_route('artist.songs.show', $song->title, [$song->artist->name, $song->id]);
}
Index view for the artists artists/index.blade.php http://i61.tinypic.com/2nqzatk.jpg
@extends('layouts.master')
@section('content')
@if(isset($songs))
<h1>All Songs</h1>
<ul class="list-group">
@foreach($songs as $song)
<li class="list-group-item">{{ link_to_artist_song($song) }}</li>
@endforeach
</ul>
@endif
@stop