rails: has_many ordering breaking when using :includes and join table in :where
Here’s the relevant code from my app
class Activity < ActiveRecord::Base
scope :with_comments, includes(:comments=>:user)
has_many :comments, :as=>:commentable, :order=>'created_at ASC'
end
irb(main):029:0> a = Activity.includes(:user).where(["users.privacy_level = ? OR users.privacy_level IS null", User::PRIVACY_PUBLIC]).where(:created_at=>(1.week.ago..Date.today.end_of_day)).where('comments_count > 5').with_comments.limit(10); 0
=> 0
irb(main):031:0> a.first.comments.each { |c| puts c.created_at };0
2012-06-13 18:38:36 UTC
2012-06-13 04:12:26 UTC
2012-06-12 14:49:29 UTC
2012-06-13 02:59:15 UTC
2012-06-13 02:46:14 UTC
2012-06-13 14:26:29 UTC
About this issue
- Original URL
- State: closed
- Created 12 years ago
- Reactions: 2
- Comments: 27 (9 by maintainers)
Any news on this issue?
This is still an issue and should be reopened.
I made a comprehensive gist to test different loading strategies (
eager_load
,includes
,includes & references
,includes & preload
): https://gist.github.com/thisismydesign/b08ba0ee3c1862ef87effe0e25386267Given the following example
I wanted to add a
first_like
association toActivity
and load it without N+1.You can see in the gist that the only working approach is:
includes
on its own can decide whether to do join or an additional query.preload
,eager_load
andreferences
force one or the other approach.preload
forces an additional query which is the working approach for ordered associations. Usingincludes
by itself will not work in every case!An additional issue I ran into was using
.limit(n)
in the association scope which breaks ordering and also the whole association with some approaches. You can test using the gist.This problem still exists in
4-1-stable
. A workaround is to usepreload
instead ofincludes
which causes Rails to create second query to fetch the associated objects, respecting the order specified on the association, rather than creating a single query with joins.Noticed this “bug” in the production environment, switching to preload didn’t help. Looking for other options.
This issue is still exists with activesupport 6.1.3.2.
Any news? It seems to be the same in Rails 5.0.6…