php - Laravel 4 Eager Loading n+1 issue -
i have troubleshoot day eager loading/n+1 issue, researched , read , watched tutorials issue, haven't solved yet. have set relationships models, when passing in data helper function got n+1 issue. want grab artist name url site.com/artist/songs , songs , display url this.
site.com/$artist/songs/$id
my artists/index.blade.php view looks http://i61.tinypic.com/2nqzatk.jpg i'm not sure 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 relationship artist model 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 song found if ($song) { // if song doesn't belong artist, throw exception redirect home, defined in global.php if ($name , $song->artist->name !== $name) { throw new illuminate\database\eloquent\modelnotfoundexception; } return $song; } // if song not found, throw exception redirect home, defined in global.php else { throw new illuminate\database\eloquent\modelnotfoundexception; } } // songs artist public static function byartist($name) { return artist::byname($name)->songs; } }
model artist.php
class artist extends eloquent { protected $fillable = []; /** * setting relationship song model easier usage * $artist->songs; */ public function songs() { return $this->hasmany('song'); } // artist name public static function byname($name) { return static::wherename($name)->first(); } }
controller: artistscontroller.php
class artistscontroller extends basecontroller { // set default layout controller protected $layout = 'layouts.master'; /** * display listing of resource. * /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 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 $song) <li class="list-group-item">{{ link_to_artist_song($song) }}</li> @endforeach </ul> @endif @stop
you never eager load anything, that's why facing n+1 issue. if right, bit hard code have here, want songs of given artist $name url, right?
so here's need make work:
// controller public function index($name) { // with('songs') eager loading related songs $this->data['artist'] = artist::with('songs')->wherename($name)->first(); $this->layout->content = view::make('artists.index', $this->data); } // problem of queries in helper: function link_to_artist_song(song $song) { return link_to_route('artist.songs.show', $song->title, [ $song->artist->name, // calling db query each song retrieve artist (despite same) $song->id]); } // instead use in view @foreach($artist->songs $song) <li class="list-group-item"> {{ link_to_route('artist.songs.show', $song->title, [$artist->name, $song->id]) }} </li> @endforeach
Comments
Post a Comment