2010-02-27 5 views
0

지금 레일즈를 통해 강렬한 acts_as_tree MySQL 쿼리에 관한 문제를 다루고 있습니다. 쿼리하는 모델은 Foo입니다. FooCity, State 또는 Country 중 하나에 속할 수 있습니다. 제 목표는 위치에 따라 Foo을 쿼리하는 것입니다. 내 위치 테이블과 같이 설정 :울트라 - 그랜드 슈퍼 acts_as_tree 레일스 쿼리

  • 나는 각각의 위치를 ​​저장하는 acts_as_tree 및 다형성 협회의 조합을 사용 locations
  • 라는 내 데이터베이스의 테이블을 가지고 City, State 또는 Country 하나있다.

은 이제 예를 들어 가정 해 봅시다 (이것은 내 표는 행 id, name, parent_id, type로 구성되어 있음을 의미), 난 상태 "캘리포니아"에 Foo의를 조회 할. "California"에 직접 속하는 Foo 옆에, "Los Angeles"와 "San Francisco"에 Foo과 같은 "California"의 모든 City에 속하는 모든 Foo을 가져야합니다. 그뿐 아니라 "California"가 들어있는 Country에 속하는 Foo을 "미국"으로 가져와야합니다.

나는 연관성이없는 몇 가지 사항을 시도해 보았습니다. 나는 몇 가지 유용한 레일스 푸를 놓치고있는 것처럼 느껴진다. 어떤 충고?

답변

0

나는 내가 넘어 그랜드 조상과 비정규 리조트 찾아이 같은 물건을 들어

.... 당신이 지금이에 대한 해결책을 발견했습니다 확신합니다. 최상의 DB 실습은 약간의 오버 헤드로 유스 케이스를 훨씬 쉽게 만들어줍니다.

예를 들어 위치 테이블에 city_id, state_id 및 country_id 열이 있고 유형이 "state"인 경우 city_id가 null입니다. type = "country"의 경우 city_id 및 state_id는 null입니다. 그런 다음 어느 노드에서든 노드의 모든 자식을 찾는 쿼리는 간단합니다. 노드 유형을 알고 있어야합니다.

간단한 before_save는 비정규 화를 수행 할 수 있습니다. 또한

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 

두 개의 정수 필드의 추가와 함께하는 중첩 된 세트 구현 같은 것을보고 싶지 (왼쪽 및 오른쪽) 할 수 있습니다 당신이 내 마음에 드는 사람이 http://github.com/collectiveidea/awesome_nested_set 인 계층 구조의 모든 노드에 대한 모든 하위 노드를 얻을 수 있습니다