Ruby on Rails: простой способ выбрать все записи вложенной модели? - PullRequest
0 голосов
/ 14 марта 2010

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

Вот настройка:

У меня есть три модели, которые вложены друг в друга (Услуги >> Теги >> Инспекции), производя код, подобный этому для маршрутов

map.resources :facilities do |facilities|
  facilities.resources :tags, :has_many => :inspections 
end

Я хотел получить все проверки для объекта, и вот что мой код закончил:

def facility_inspections
  @facility = Facility.find(params[:facility_id])
  @inspections = []
  @facility.tags.each do |tag| 
    tag.inspections.each do |inspection|
      @inspections << inspection
    end
  end
end

Это работает, но это лучший способ сделать это - я думаю, что это громоздко.

Ответы [ 2 ]

3 голосов
/ 14 марта 2010

Вы можете использовать has_many :through ассоциацию. В ваших моделях:

# Facility model
has_many :tags
has_many :inspections, :through => :tags

# Tag model
belongs_to :facility
has_many :inspections

И вы можете получить все проверки, как это:

@inspections = Facility.find(params[:facility_id]).inspections

Но если у вас есть отношение HABTM между Facility и Tag, оно будет более сложным, и вам придется написать некоторые инструкции SQL, например:

@inspections = Inspection.all(:joins => "INNER JOIN tags ON tags.id = inspections.tag_id INNER JOIN facilities_tags ON tags.id = facilities_tags.tag_id", :conditions => ["facilities_tags.facility_id = ?", params[:facility_id] )

Конечно, приведенный выше код зависит от структуры вашей таблицы. Если покажешь, то будет проще дать правильный ответ :). Надеюсь, это поможет!

0 голосов
/ 14 марта 2010
@facility = Facility.find(params[:facility_id], :include => {:tags => :inspections})

При этом выполняется один запрос к базе данных (ваше первоначальное решение будет использовать многие из них) и возвращается объект объекта со всеми тегами и проверками. Тогда вы можете сделать что-то вроде:

@inspections = @facility.tags.map(&:inspections).flatten
...