我有一个模型播放列表,和一个模型用户,通过一个连接模型播放列表用户,这两个用户彼此有很多。
在“播放列表”的“显示操作”中,我要打印播放列表中所有用户的列表,以及与每个用户关联的前两个播放列表(按顺序排列:歌曲计数)。为了只进行一个查询,我急切地将Playlist表和用户一起加载。
现在我有:
播放列表/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

当我删除排序时,查询速度非常快。但是在排序时,它非常慢,因为数据库显然必须先查询每个播放列表,然后才能对它们进行排序。
我可以在原始查询中订购播放列表吗?

最佳答案

实际上当你这样做的时候:

user.playlists.order(:song_count).reverse

你不能利用急切的负载,你每次都要重做查询。
由于急切地加载,您将集合保存在内存中,因此可以使用类似sort的ruby方法对其进行排序:
user.playlists.sort_by {|pl| -pl.song_count }

10-07 23:26