Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eager loading nested association and scope

I'm a beginner and it's hard to explain my problem:

My models:

class Skill  
  has_many :categories
  has_many :positions, :through => :categories
end

class Category
  belongs_to :skill
  has_many :positions  
end

class Position
  belongs_to :category
  has_one :skill, :through => :category    
end

I can successfully eager load everything, like this:

@skills = Skill.includes(:positions)

However sometimes I want to apply a scope on the Positions:

class Position
...
  scope :active, where(:hidden => false)
end

I wish I could do:

@skills = Skill.includes(:positions.active)

Instead, I apply the scope in the views, but the eager loading doesn't work anymore:

<%= skill.positions.acitve ... %>

Is it possible to have both eager loading and scope?

like image 472
Martin Petrov Avatar asked May 29 '11 19:05

Martin Petrov


1 Answers

You could use another association:

class Skill  
  has_many :categories
  has_many :positions, :through => :categories
  has_many :active_positions, :through => :categories
end

class Category
  belongs_to :skill
  has_many :positions  
  has_many :active_positions, :class_name => "Position", :conditions => {:hidden => false}
end

class Position
  belongs_to :category
  has_one :skill, :through => :category    
end

And then

@skills = Skill.includes(:active_positions)

But then you'll get two associations. If you ever use skill.positions, all the skill's positions will be loaded from the database. You should only use skill.active_positions.

like image 92
Michaël Witrant Avatar answered Oct 25 '22 11:10

Michaël Witrant