我有一个模型播放列表和一个模型用户,它们彼此相互拥有,通过连接模型PlaylistUser。
在我的播放列表#show action上,我想要打印所有播放列表用户的列表,以及与每个用户相关联的前两个播放列表(按照:song_count排序)。为了使这个只有一个查询,我急切地将播放列表表与用户一起加载。
现在我在拥有的东西:
播放列表/ show.html.erb
<% @playlist = Playlist.find(params[:id]) %>
<% @playlist_users = @playlist.users.includes(:playlists)
<% @playlist_users.each do |user| %>
<%= user.name %>
<%= user.playlists.order(:song_count).reverse.first.name %>
<%= user.playlists.order(:song_count).reverse.second.name %>
<% end %>
模型
class User < ActiveRecord::Base
has_many :playlist_users
has_many :playlists, :through => :playlist_users
end
class PlaylistUser < ActiveRecord::Base
belongs_to :playlist
belongs_to :user
end
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :users, :through => :playlist_users
end
当我删除排序时,查询非常快。但是通过排序,它非常慢,因为数据库显然必须先查询每个播放列表才能订购它们。
我可以在原始查询中订购播放列表吗?
答案 0 :(得分:2)
实际上当你这样做时:
user.playlists.order(:song_count).reverse
您不利用eagerload,每次都重做查询。
感谢eagerloading你在内存中拥有了这个集合,所以你可以使用像sort这样的ruby方法对它进行排序:
user.playlists.sort_by {|pl| -pl.song_count }