2

I am running Ruby on Rails 3.1. I would like to eager loading "second degree" associated objects by applying some conditions, but I am in trouble.

It seems that I already solved part of my issue by using:

article_categories =
  article
    .categories
    .includes(:comments => [:category_relationships])
    .where(:category_relationships => {:user_id => @current_user.id})

where involved classes are stated as the following:

class Category < ActiveRecord::Base
  has_many :comment_relationships
  has_many :comments,
    :through => :comment_relationships

  ...
end

class Comment < ActiveRecord::Base
  has_many :category_relationships
  has_many :categories,
    :through => :category_relationships

  ...
end

The above code (it seems to do it right):

  1. loads all categories by caring the has_many :through :category_relationships association (that is, by caring the .where(:category_relationships => {:user_id => @current_user.id}) condition);
  2. eager loads all article.comments.where(:user_id => @current_user.id).

However, I would like to make some more:

  1. to order retrieved categories by a :position attribute present in category_relationships so that the resulting article_categories are ordered by position;
  2. to eager load also category_relationship objects where user_id == @current_user.id since the above code doesn't make that.

How can I make that by taking advantage from the eager loading?

Community
  • 1
  • 1
Backo
  • 18,291
  • 27
  • 103
  • 170

1 Answers1

0

The solution:

  1. .order("category_relationships.position")

  2. Imagine eager loading is cartessian product with some filtering so "where" is filtering the end result of include (left join really). But it can be done with where with subquery which first will filter categories by user then your where can be removed.

gertas
  • 16,869
  • 1
  • 76
  • 58