У меня есть модель City
:
class City
belongs_to :country
end
И модель Улица:
//street has an attribute 'Type' which can be 1, 2 or 3
class Street
belongs_to City
end
Я хочу, чтобы все города в Хорватии, включая улицы, которые относятся к типу 2
Так что-то вроде этого:
cities = City.find_by_country("Croatie").include_streets_where(type: 2)
поэтому я получаю что-то вроде этого:
[
{
name: "Zagreb",
country: "Croatia",
streets: [{name: "street1", type: 2},{name: "street2", type: 2}]
},
{
name: "Split",
country: "Croatia",
streets: [{name: "street3", type: 2},{name: "street4", type: 2}]
}
]
Мое решение состоит в том, чтобы сначала получить города по названию страны и пройти через каждый город, чтобы запросить его на улицах. Но я предполагаю, что есть лучший способ.
Я предполагаю, что ваш город has_many :streets
, а ваш класс Country имеет name
атрибута.
Двухслойный цикл не так эффективен, как INNER JOIN, который вы можете собрать с помощью этого: (Вы можете посмотреть на SQL, который он создает, добавив к концу .to_sql
.)
cities = City.where(country: Country.find_by_name("Croatie"))
.joins(:streets).where(streets: { type: 2 })
Это вернет список объектов city
соответствующих вашим критериям. Теперь, чтобы получить его в указанном вами формате, вам нужно сделать некоторое форматирование на стороне Ruby, поскольку возвращаемое по умолчанию значение не является типом массива. Это предполагает, что вы хотите массив хешей.
formatted_list = cities.map do |city|
{ name: city.name,
country: city.country.name,
streets: list_of_streets_with_type(city.streets) }
end
def list_of_streets_with_type(streets)
streets.map do |street|
{ name: street.name,
type: street.type }
end
end
В конце концов, formatted_list
будет возвращать то, что вы хотели. (Отказ от ответственности: я не проверял синтаксис, но общая идея есть. Попробуйте, он должен работать)