Ультра-грандиозный супер-рельс

0

В настоящее время я имею дело с проблемой, связанной с интенсивным запросом mysqls_as_tree MySQL через рельсы. Модель, которую я запрашиваю, составляет Foo. A Foo может принадлежать любому City, State или Country. Моя цель - запросить Foo на основе их местоположения. Таблица моих местоположений настроена так:

  • У меня есть таблица в моей базе данных locations
  • Я использую комбинацию act_as_tree и полиморфных ассоциаций для хранения каждого отдельного местоположения либо как City, State или Country. (Это означает, что моя таблица состоит из строк id, name, parent_id, type)

Скажем, например, я хочу запросить Foo в состоянии "Калифорния". Помимо Foo, которые прямо принадлежат "Калифорнии", я должен получить все Foo, которые принадлежат каждому City в "Калифорнии", например Foo в "Лос-Анджелесе" и "Сан-Франциско". Не только это, но я должен получить любой Foo, принадлежащий Country, в котором находится "Калифорния", "Соединенные Штаты".

Я пробовал несколько вещей с ассоциациями безрезультатно. Я чувствую, что мне не хватает некоторых супер-полезных Rails-фу здесь. Любые советы?

1 ответ

0
Лучший ответ

Я уверен, что вы нашли решение для этого до сих пор....

Для таких вещей я считаю, что я прибегаю к денормализации великих предков и за его пределами. Несмотря на то, что это не самая лучшая практика 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню