2011-11-28 70 views
7
render :json => { 
    "playlist" => playlist_description, 
    "songs" => @playlist.songs.as_json(:include => {:playlist_songs => {:only => [:id, :position]}}) 
    } 

上面的代码导致1 + N查询到数据库,一个为每首歌曲加载playlist_songs。 播放列表已预载入@playlist。Rails:渴望加载as_json包括

这太慢了,我该如何优化?

回答

17

我的猜测:你不是急于加载此刻的playlist_songs。您目前正在等待as_json调用 - 之后所有歌曲都已加载 - 然后代码必须遍历每首歌曲,然后获取playlist_songs。

我的猜测(这是完全未经测试,可能包括错误)

@playlist.songs.all(:include => :playlist_songs).as_json(:include => {:playlist_songs => {:only => [:id, :position]}}) 

AFAICT,这应该第一贪婪加载的所有歌曲的playlist_songs ...然后呈现为JSON。

1
render :json => { 
    "playlist" => playlist_description, 
    "songs" => @playlist.songs.all.as_json(:include => {:playlist_songs => {:only => [:id, :position]}}) 
} 

^猜

4

我强烈建议与JSON构建器集成,如rabl。它将使您的生活更容易前进10倍,并且非常好地分离JSON表示的“视图”。几个月前我做了开关,并没有回头。

在你的控制器:

@playlist = Playlist.where(:id => params[:id]).includes(:playlist_songs) 

然后Rabl的模板可能是这样的:

object @playlist 
attribute :description 
child :playlist_songs do 
    attributes :id, :position 
end