2010-03-05 24 views
7

¿Hay alguna forma de anidar ámbitos con nombre dentro de cada uno de los otros modelos?Ruby on Rails: ámbitos con nombre anidados

Ejemplo:

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 

¿Hay alguna manera agradable para mí encontrar una empresa, mientras incluyendo a los empleados y cónyuges como este:
Company.with_employees.with_spouse.find(1)
o es necesario para mí definir otra named_scope en la compañía:
:with_employees_and_spouse, :include => {:employees => :spouse}

en este ejemplo artificial, no es demasiado malo, pero la anidación es mucho más profundo en mi solicitud, y me gustaría que no tuviera a una dd código no DRY que redefine la inclusión en cada nivel de la anidación.

+2

De buscadores rails3 lo que sé http://m.onkey.org/2010/1/22/active-record-query-interface mejorado en la zona de encadenamiento de filtro . – clyfe

Respuesta

0

Necesita definir todo el tiempo todas sus condiciones. Sin embargo, se puede definir un método para combinar algunos 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

En su método with_employees_with_spouse, encadenó junto con_employees con el submodelo with_spouse. Eso fue intencionado, ya que eso es lo que estoy buscando una manera de hacer. –

+0

sí, mi ejemplo no es muy bueno, pero no hay una manera realmente buena de hacerlo :( – shingara

1

Se puede utilizar por defecto de alcance

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 

Entonces esto debería funcionar. Aunque no lo he probado.

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

Yo recomendaría mantenerme alejado de default_scope. Es difícil dar un paso al costado cuando lo necesitas y se interpone en el camino más seguido de lo que piensas. –

+0

Lo refinaría para usar únicamente default_scope para ordenar y nunca usarlo para refinar o limitar los registros que devuelve una consulta. –

0

probar esto

Company.with_employees.merge(Employees.with_spouse)