2010-03-05 106 views
7

是否有任何方法将来自不同模型的命名范围嵌套在彼此之内?Ruby on Rails:嵌套命名示波器

例子:

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 

有我找到一个公司,而包括员工及配偶任何像这样的好方法:
Company.with_employees.with_spouse.find(1)
或者是我有必要在公司定义另一个named_scope:
:with_employees_and_spouse, :include => {:employees => :spouse}

在这个人为的例子,这不是太糟糕,但嵌套在我的应用更加深入,我想,如果我没有到dd un-DRY代码重新定义嵌套的每个级别的include。

+2

据我所知Rails3中发现者http://m.onkey.org/2010/1/22/active-record-query-interface在过滤器链接方面有改进。 – clyfe 2010-03-05 22:11:25

回答

0

您需要定义所有时间的所有条件。但是你可以定义一些方法,一些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 
+0

在with_employees_with_spouse方法中,您使用子模型的with_spouse将_employees链接在一起。那是有意的,因为那正是我正在寻找的一种方法。 – 2010-03-05 22:41:01

+0

是的,我的例子并不是很好,但是没有真正的好办法:( – shingara 2010-03-06 08:35:48

1

您可以使用默认作用域

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 

那么这应该工作。我还没有测试过它。

Company.find(1)   # includes => [:employee => :spouse] 
+0

我建议远离default_scope。当你需要的时候,很难一边踩一边,它比你想象的更频繁。 – 2011-04-26 13:16:37

+0

我会优化到只使用default_scope进行排序,并且从不使用它来优化或限制查询返回的记录。 – 2012-03-11 03:00:51

0

试试这个

Company.with_employees.merge(Employees.with_spouse)