Joe Morano
Joe Morano

Reputation: 1895

How can I efficiently order eager loaded records?

I have a model Playlist, and a model User, both of which have_many of each other, through a join model PlaylistUser.

On my playlists#show action, I want to print a list of all of a Playlist's Users, along with the first two Playlists (ordered by :song_count) associated with each of those Users. To make this only one query, I eager loaded the Playlist table along with the Users.

Right now here's what I have:

playlists/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 %>

models

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

When I remove the ordering, the query is extremely fast. But with the ordering, it's very slow, because the database apparently has to query each Playlist before it can order them.

Can I order the Playlists in the original query?

Upvotes: 1

Views: 43

Answers (1)

apneadiving
apneadiving

Reputation: 115541

actually when you do:

user.playlists.order(:song_count).reverse

You dont leverage the eagerload, you redo queries each time.

Thanks to eagerloading you have the collection in memory, so you can sort it using ruby method like sort:

user.playlists.sort_by {|pl| -pl.song_count }

Upvotes: 2

Related Questions