2010-02-27 5 views
0

En ce moment je suis confronté à un problème concernant une requête intense de MySQL acts_as_tree via des rails. Le modèle que j'interroge est Foo. Un Foo peut appartenir à l'un City, State ou Country. Mon objectif est d'interroger Foo s en fonction de leur emplacement. est table Panset Mes emplacements comme autant:Ultra-grand super acts_as_tree rails requête

  • J'ai une table dans ma base de données appelée locations
  • J'utilise une combinaison d'associations de acts_as_tree et polymorphes pour stocker chaque emplacement individuel soit comme un City, State ou Country. (Cela signifie que ma table se compose des lignes id, name, parent_id, type)

Disons que, par exemple, je veux interroger Foo s dans l'état « Californie ». A côté de Foo s qui appartiennent directement à "California", je devrais obtenir tous les Foo s qui appartiennent tous les City dans "California" comme Foo s dans "Los Angeles" et "San Francisco". Non seulement cela, mais je devrais obtenir Foo s qui appartiennent à la Country que "Californie" est, "États-Unis".

J'ai essayé quelques choses avec des associations en vain. J'ai l'impression de manquer quelques Rails-fu super utiles ici. Aucun conseil?

Répondre

0

Je suis sûr que vous avez trouvé une solution pour cela maintenant ....

Pour des trucs comme ça, je trouve que je station à dénormaliser les grands ancêtres et au-delà. Bien que ce ne soit pas la meilleure pratique de la DB, cela rend les cas d'utilisation beaucoup plus faciles avec juste un peu de frais généraux. Ainsi, par exemple, votre table d'emplacements aurait une colonne city_id, state_id et country_id et dans les cas où le type est "state", city_id est null. et pour type = "country" city_id et state_id sont null. Alors à tout moment votre requête pour trouver tous les enfants d'un nœud donné est simple, vous devez juste savoir quel type de nœud vous recherchez.

Un before_save simple peut faire la dénormalisation.

belongs_to :city, :class_name => "Location", :foreign_key => :city_id 
belongs_to :state, :class_name => "Location", :foreign_key => :state_id 
belongs_to :country, :class_name => "Location", :foreign_key => :country_id 

#might want to throw in some validation that one of the ids is set... 
def before_save 
    self.state_id = self.city.state_id if city_id && city 
    self.country_id = self.state.country_id if state_id && state 
end 

Sinon, vous voudrez peut-être regarder quelque chose comme la mise en œuvre de jeu imbriqué avec l'ajout de deux champs entiers (gauche et droite) vous permet d'obtenir toutes les sous-noeuds pour un nœud dans la hiérarchie mon préféré est http://github.com/collectiveidea/awesome_nested_set