【问题标题】:Rails: Eager loading as_json includesRails:渴望加载 as_json 包括
【发布时间】:2011-12-11 07:57:01
【问题描述】:
render :json => {
"playlist" => playlist_description,
"songs" => @playlist.songs.as_json(:include => {:playlist_songs => {:only => [:id, :position]}})
}
上面的代码对数据库进行了 1+N 次查询,一次为每首歌曲加载 playlist_songs。
播放列表预加载在@playlist 中。
这么慢,如何优化?
【问题讨论】:
标签:
ruby-on-rails
activerecord
【解决方案1】:
我的猜测:您目前并没有急切地加载 playlist_songs。您目前正在等待 as_json 调用 - 之后所有歌曲都已加载 - 然后代码必须遍历每首歌曲并获取 playlist_songs。
我的猜测(这完全未经测试,可能包含错误)
@playlist.songs.all(:include => :playlist_songs).as_json(:include => {:playlist_songs => {:only => [:id, :position]}})
AFAICT,这应该首先急切地加载所有歌曲和 playlist_songs...然后渲染为json。
【解决方案2】:
我强烈建议与 rabl 等 JSON 构建器集成。它将使您的生活更轻松 10 倍,并且非常好地分离 JSON 表示的“视图”。几个月前我做出了改变,并没有回头。
在您的控制器中:
@playlist = Playlist.where(:id => params[:id]).includes(:playlist_songs)
那么 rabl 模板可能是这样的:
object @playlist
attribute :description
child :playlist_songs do
attributes :id, :position
end
【解决方案3】:
render :json => {
"playlist" => playlist_description,
"songs" => @playlist.songs.all.as_json(:include => {:playlist_songs => {:only => [:id, :position]}})
}
^猜