2010-03-14 2 views
0

Любопытно, что я потратил некоторое время на попытку получить массив всех записей в вложенной модели. Я просто хочу убедиться, что нет лучшего способа.Ruby on Rails: простой способ выбрать все записи вложенной модели?

Вот установка:

У меня есть три модели, которые вложены друг под другом (Услуги >> Метки >> осмотры), производя такой код для routes.rb:

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

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

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 

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

ответ

3

Вы можете использовать ассоциацию 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 соотношение между фондом и 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

Spot on Klew, все еще немного смущенный, но мне все равно, потому что это здорово. Спасибо, и вы правы, на данный момент это один-ко-многим, но в будущем, если я столкнусь с чем-то, что есть HABTM, хорошо знать, что мне нужно написать несколько sql. Спасибо! –

0
@facility = Facility.find(params[:facility_id], :include => {:tags => :inspections}) 

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

@inspections = @facility.tags.map(&:inspections).flatten 
Смежные вопросы