Ruby on Rails: Nested named scopes
Asked Answered
C

3

8

Is there any way to nest named scopes inside of each other from different models?

Example:

class Company
  has_many :employees
  named_scope :with_employees, :include => :employees
end
class Employee
  belongs_to :company
  belongs_to :spouse
  named_scope :with_spouse, :include => :spouse
end
class Spouse
  has_one :employee
end

Is there any nice way for me to find a company while including employees and spouses like this:
Company.with_employees.with_spouse.find(1)
or is it necessary for me to define another named_scope in Company:
:with_employees_and_spouse, :include => {:employees => :spouse}

In this contrived example, it's not too bad, but the nesting is much deeper in my application, and I'd like it if I didn't have to add un-DRY code redefining the include at each level of the nesting.

Cristincristina answered 5/3, 2010 at 19:58 Comment(1)
From what i know rails3 finders m.onkey.org/2010/1/22/active-record-query-interface improved in the filter chaining area.Isborne
R
1

You can use default scoping

class Company
  default_scope :include => :employees
  has_many :employees
end

class Employee
  default_scope :include => :spouse
  belongs_to :company
  belongs_to :spouse
end

class Spouse
  has_one :employee
end

Then this should work. I have not tested it though.

Company.find(1)          # includes => [:employee => :spouse]
Roadrunner answered 11/3, 2010 at 19:54 Comment(2)
I'd recommend staying away from default_scope. It's difficult to side step when you need to and it gets in the way more often than you think.Deathless
I'd refine that to only using default_scope for ordering and never use it to refine or limit the records a query returns.Emigration
P
0

You need define all the time all of your conditions. But you can define some method to combine some named_scope


class Company
  has_many :employees
  named_scope :with_employees, :include => :employees
  named_scope :limit, :lambda{|l| :limit => l }

  def with_employees_with_spouse
    with_employees.with_spouse
  end

  def with_employees_with_spouse_and_limit_by(limit)
    with_employees_with_spouse.limit(limit)
  end

end
class Employee
  belongs_to :company
  belongs_to :spouse
  named_scope :with_spouse, :include => :spouse
end
class Spouse
  has_one :employee
end
Pasquinade answered 5/3, 2010 at 22:19 Comment(2)
In your with_employees_with_spouse method, you chained together with_employees with the submodel's with_spouse. Was that intended, since that is what I'm looking for a way to do.Cristincristina
yes my exemple is not really great but there are no really good way to do :(Pasquinade
S
0

try this

Company.with_employees.merge( Employees.with_spouse)
Steck answered 23/4, 2014 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.