В настоящее время я имею дело с проблемой, связанной с интенсивным запросом mysqls_as_tree MySQL через рельсы. Модель, которую я запрашиваю, составляет Foo
. A Foo
может принадлежать любому City
, State
или Country
. Моя цель - запросить Foo
на основе их местоположения. Таблица моих местоположений настроена так:
locations
City
, State
или Country
. (Это означает, что моя таблица состоит из строк id
, name
, parent_id
, type
)Скажем, например, я хочу запросить Foo
в состоянии "Калифорния". Помимо Foo
, которые прямо принадлежат "Калифорнии", я должен получить все Foo
, которые принадлежат каждому City
в "Калифорнии", например Foo
в "Лос-Анджелесе" и "Сан-Франциско". Не только это, но я должен получить любой Foo
, принадлежащий Country
, в котором находится "Калифорния", "Соединенные Штаты".
Я пробовал несколько вещей с ассоциациями безрезультатно. Я чувствую, что мне не хватает некоторых супер-полезных Rails-фу здесь. Любые советы?
Я уверен, что вы нашли решение для этого до сих пор....
Для таких вещей я считаю, что я прибегаю к денормализации великих предков и за его пределами. Несмотря на то, что это не самая лучшая практика DB, это облегчает использование приложений с небольшим количеством накладных расходов.
Так, например, ваша таблица местоположений имела бы столбец city_id, state_id и country_id, а в тех случаях, когда тип "state", city_id равен null. и для type = "country" city_id и state_id имеют значение null. Тогда в любой момент ваш запрос на поиск всех дочерних элементов данного node прост, вам просто нужно знать, какой тип node вам нужен.
Простой 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
В качестве альтернативы вам может понадобиться посмотреть что-то вроде реализации вложенного набора, которая с добавлением двух целых полей (слева и справа) позволяет вам получить все подузлы для любого node в иерархии, мой любимый - http://github.com/collectiveidea/awesome_nested_set