rails: запрос has_many для получения списка объектов

0

У меня есть модель 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}]
 }
]

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

Теги:

1 ответ

1

Я предполагаю, что ваш город 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 будет возвращать то, что вы хотели. (Отказ от ответственности: я не проверял синтаксис, но общая идея есть. Попробуйте, он должен работать)

Ещё вопросы

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