Rails:预加载as_json includes

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

上述代码会导致1+N个对数据库的查询,每首歌曲都需要查询一次playlist_songs。 @playlist中已经预先加载了播放列表。
这样做速度很慢,如何优化?
3个回答

22

我的猜测:您目前没有预加载播放列表歌曲。您现在正在等待as_json调用 - 此后将加载所有歌曲 - 然后代码必须遍历每首歌曲并获取播放列表中的歌曲。

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

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

根据我所知,这应该首先急切地加载所有的歌曲和播放列表歌曲...然后以json格式渲染。


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

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

^ 猜测


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接