Я работаю над приложением, которое действует как каталог мест и (в настоящее время, но, возможно, не всегда) позволяет фильтровать объекты определенного предприятия по 1 городу, 1 району и 1 категории. Категории могут быть вложенными, и поэтому они имеют parent_id. Ассоциации можно понять, посмотрев код модели ниже (все довольно просто). Пока что все идет гладко, но остался один помеха.
Сначала несколько важных замечаний, которые повлияют на ответы.
1. Я использую will_paginate для разбиения на страницы в ассоциации мест. При этом я не могу разбить на страницы в массиве. Ну, я мог бы , но производительность была бы проблемой внизу.
2. Я использую модель тегов в качестве объекта связи между бизнесом и связанными с ним категориями. В настоящее время интерфейс настроен только для того, чтобы разрешить привязку одной категории к какой-либо конкретной компании, и должен быть присоединен хотя бы один . Я планирую позже расширить интерфейс для общедоступных страниц, чтобы разрешить фильтрацию по нескольким категориям, поэтому нельзя вносить изменения в эту часть структуры приложения, если не существует намного, гораздо лучшего способа выполнения этого .
3. Возможное решение, которое могло бы (мы надеемся) существовать - это псевдоним объединения таблиц в Arel или области действия, позволяющей категориям самостоятельно присоединяться к себе, чтобы получить к родителю. В настоящее время я бы счел это приемлемым, если бы в решении предполагалось, что будет не более 1 уровня вложенности. Однако эта жертва является последним средством, поскольку она действительно ослабит функциональность, которую я хочу представить в будущем.
4. В связи с последним пунктом я рассмотрел will_paginate/array
, но был напуган их отказом от ответственности («Если вы знаете, что делаете, и действительно должны разбивать массивы на части, эта функция явно "). Вспоминая ночные кошмары о производительности, с которыми я сталкивался в прошлом, когда пытался развернуть свой собственный плагин для разбивки на страницы, я бы хотел этого избежать, если кто-то не сможет адекватно объяснить мне последствия для производительности такого решения.
5. Этот сайт должен быть в состоянии принять удары. В настоящее время все кэшируется, и попадания в базу данных, не связанные с кэшем, относительно редки. Это должно оставаться таким.
Теперь вопрос, который я хочу задать.
Справочная информация : для некоторых спецификаций дизайна общедоступных представлений требуется, чтобы все объекты текущего города отображались в списке и группировались по родительской категории (не нужно отображать подкатегории, но все объекты теги, чьи предприятия принадлежат подкатегории, также должны быть сгруппированы с местами, теги которых принадлежат родителю). Затем эти объекты сортируются по родительской категории, а затем сортируются по названию предприятия, которому принадлежит объект. Это должна быть плоская ассоциация, которая затем подается в will_paginate. Это обрабатывает запрос ActiveRecord, который в дальнейшем я буду называть @venues
, затем выгружается в JSON, кэшируется и выводится на страницу.
Вопрос : Как мне построить @venues
с указанной группировкой / упорядочением, чтобы эти места можно было правильно разбить на страницы и отображать в соответствии со спецификациями этого интерфейса?
приложение / модели / business.rb
# Fields: id, name, description, keywords, ...
class Business < ActiveRecord::Base
has_many :tags, :dependent => :destroy
has_many :categories, :through => :tags
has_many :venues, :dependent => :destroy
has_many :cities, :through => :venues
has_many :neighborhoods, :through => :venues
end
приложение / модели / venue.rb
# Fields: id, business_id, city_id, neighborhood_id, ...
class Venue < ActiveRecord::Base
belongs_to :business
belongs_to :city
belongs_to :neighborhood
end
приложение / модели / tag.rb
# Fields: id, category_id, business_id, ...
class Tag < ActiveRecord::Base
belongs_to :business
belongs_to :category
belongs_to :venue
end
приложение / модели / category.rb
# Fields: id, parent_id, name, description, ...
class Category < ActiveRecord::Base
has_many :tags, :dependent => :destroy
end
приложение / модели / city.rb
# Fields: id, name, description, ...
class City < ActiveRecord::Base
has_many :neighborhoods, :dependent => :destroy
has_many :venues
end
приложение / модели / neighborhood.rb
# Fields: id, city_id, name, description
class Neighborhood < ActiveRecord::Base
belongs_to :city
has_many :venues
has_many :businesses, :through => :venues
end
Это был один дурак, чтобы объяснить, и я могу предоставить больше информации, если это будет необходимо.
P.S. Использование Rails 3.0.9 для этого приложения с MySQL.
P.S.S. Мне также интересны шаблоны или гемы, которые упрощают этот вид фильтрации на основе возможных значений полей нескольких вложенных ассоциаций. Я предоставлю upvote + accept + bounty тому, кто сможет предоставить точное решение, используя драгоценный камень модели вложенного набора, такой как Awesome Nested Set, для группировки / сортировки / разбиения на страницы таким образом.