2013-05-16 2 views
1

У меня есть 3 модели:Рельсы и RABL сортировать ребенка по другой модели, что она принадлежит к

class City < ActiveRecord::Base 
    has_many :buildings 
end 
class Company < ActiveRecord::Base 
    has_many :buildings 
end 
class Building < ActiveRecord::Base 
    belongs_to :city 
    belongs_to :company 
end 

Мне нужно показать здание в каждом городе, но отсортирован по своей компании, как это:

city1 
    company1 
    building1 
    building2 
    company2 
    building3 
city2 
    company1 
    building5 
    building6 
    building4 
    company2 
    building7 
    building8 

Я не могу понять, как сделать запрос, или как использовать RABL правильно генерировать эту структуру вывода

EDIT:

Это то, что я придумал на данный момент:

cities_controlles.rb:

def index 
    @cities = City.all 
    @companies = Company.includes(:buildings) 
end 

index.json.rabl:

collection @cities 
attributes :id, :name 
node :companies do |city| 
    @companies.map do |company| 
    { id: company.id, name: company.name, buildings: 
    company.buildings.map do |building| 
     if building.city_id == city.id 
     { id: building.id, name: building.name } 
     end 
    end.compact 
    } 
    end 
end 

ответ

-1

Существует много способов сделать это в зависимости от того, как следует использовать результат.

Первый способ:

SELECT 
    cities.name, companies.name, buildings.name 
FROM 
    cities 
LEFT JOIN 
    companies ON companies.city_id = city.id 
LEFT JOIN 
    buildings ON buildings.city_id = city.id 
ORDER BY 
    cities.name, companies.name, buildings.name 

Rezult должно быть то вроде этого:

city1 | company1 | building1 
city1 | company1 | building2 
city1 | company2 | building3 
city2 | company1 | building4 
city2 | company1 | building5 
city2 | company1 | building6 
city2 | company2 | building7 
city2 | company2 | building7 

И вы можете делать все, что вы хотите с этой таблицей.

Второй способ (с использованием агрегатной функции, чтобы получить список зданий для города и компании):

SELECT 
    cities.name, companies.name, GROUP_CONCAT(buildings.name) 
FROM 
    cities 
LEFT JOIN 
    companies ON companies.city_id = city.id 
LEFT JOIN 
    buildings ON buildings.city_id = city.id 
ORDER BY 
    cities.name, companies.name 
GROUP BY 
    cities.name, companies.name 

Таким образом Rezult должно быть то вроде этого:

city1 | company1 | building1, building2 
city1 | company2 | building3 
city2 | company1 | building4, building5, building6 
city2 | company2 | building7, building8 

ПРИМЕЧАНИЕ Имя агрегированной функции (GROUP_CONCAT - для MySQL) отличается в СУБД. Например, в firebird это «СПИСОК»

Смежные вопросы