Ультра-грандиозный супер-рельс - PullRequest
0 голосов
/ 27 февраля 2010

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

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

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

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

1 Ответ

0 голосов
/ 29 мая 2010

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

Для подобных вещей я нахожу, что прибегаю к денормализации великих предков и не только. Несмотря на то, что это не лучшая практика работы с БД, она значительно упрощает использование с небольшими накладными расходами.

Так, например, ваша таблица местоположений будет иметь столбцы city_id, state_id и country_id, а в случаях, когда типом является «state», city_id равен нулю. а для type = "country" city_id и state_id равны нулю. Тогда в любой момент ваш запрос на поиск всех дочерних элементов данного узла прост, вам просто нужно знать, какой тип узла вы ищете.

Простое 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...