2010-03-05 3 views
7

Y a-t-il un moyen d'imbriquer des étendues nommées entre elles à partir de modèles différents?Ruby on Rails: étendues nommées imbriquées

Exemple:

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 

est-il un moyen agréable pour moi de trouver une entreprise tout en incluant les employés et les conjoints comme celui-ci:
Company.with_employees.with_spouse.find(1)
ou est-il nécessaire pour moi de définir une autre named_scope dans la société:
:with_employees_and_spouse, :include => {:employees => :spouse}

utilisées dans cet exemple, il est pas trop mal, mais l'imbrication est beaucoup plus profond dans ma demande, et je voudrais si je ne devais pas un dd code non-DRY redéfinissant l'include à chaque niveau de l'imbrication.

+2

D'après ce que je sais trouveurs rails3 http://m.onkey.org/2010/1/22/active-record-query-interface amélioré dans la zone enchaînant filtre . – clyfe

Répondre

0

Vous devez définir en permanence toutes vos conditions. Mais vous pouvez définir une méthode pour combiner certains 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

Dans votre méthode with_employees_with_spouse, vous avez chaîné avec_employés avec le sous-modèle with_spouse. Était-ce prévu, puisque c'est ce que je cherche un moyen de faire. –

+0

oui mon exemple n'est pas vraiment génial mais il n'y a pas vraiment de bonne façon de faire :( – shingara

1

Vous pouvez utiliser portée par défaut

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 

Ensuite, cela devrait fonctionner. Je ne l'ai pas testé cependant.

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

Je vous recommande de ne pas utiliser default_scope.Il est difficile de passer du bon pied quand vous en avez besoin et ça vous gêne plus souvent que vous ne le pensez. –

+0

J'affinerais cela en utilisant seulement default_scope pour la commande et ne l'utiliserai jamais pour affiner ou limiter les enregistrements qu'une requête renvoie. –

0

essayer cette

Company.with_employees.merge(Employees.with_spouse)