2009-09-02 6 views
1

J'ai essayé de faire des choses en utilisant mes relations Rails plutôt que de tirer de grandes jointures SQL, mais je ne peux pas envelopper ma tête autour de celui-ci ...rails moyenne entre plusieurs modèles

J'ai 3 modèles

Hôtels Chambres Articles disponibles

Ils ont tous le has_many approprié et belongs_to relations.

Ce que je veux faire est sur la page d'aperçu énumérant les hôtels d'une ville particulière, je veux lister le prix le plus bas trouvé pour chaque hôtel.

maintenant dans SQL Je voudrais bien sûr faire le bit de code en bas, mais dans des rails que je pouvais faire quelque chose comme ça ...

def self.price 
    Available.minimum(:price, 
       :conditions => [ "price <> 0" ]) 
    end 

Bien sûr, tire juste le prix le plus bas de tous eux, pas une pièce d'identité spécifique

le problème est la relation Hotel.find (1234) .rooms.availables

Mais je voudrais faire quelque chose comme ça qui pourrait aller dans ma boucle sans avoir à faire référence à la ID?

SELECT MIN(availables.price) 

FROM availables 

INNER JOIN rooms ON rooms.id = availables.room_id 
INNER JOIN hotels ON hotels.id = rooms.hotel_id 

WHERE hotels.id = 5077 and rooms.private = 0 and availables.price <> 0 

Répondre

1

Vous pouvez accomplir ceci en établissant un has_many: à travers la relation sur l'hôtel:

class Hotel < ActiveRecord::Base 
    has_many :rooms 
    has_many :availables, :through => :rooms 

    # If you want "rooms"."private" condition, use these... 
    has_many :public_rooms, :class_name => 'Room', :conditions => {:private => 0} 
    has_many :public_availables, :through => :public_rooms, :source => :availables 

    # This caches the value (potentially saving you db hits) for the 
    # lifetime of the object, which you may or may not want depending 
    # on your needs... 
    def cheapest_available 
    @cheapest_available ||= availables.minimum(:price, :conditions => ['availables.price > ?', 0]) 
    end 
end 

maintenant vous pouvez traverser al l des hôtels dans une ville particulière affichant le prix le plus bas:

@city.hotels.each do |hotel| 
    puts "#{hotel.name}: #{hotel.cheapest_available}" 
end 
1

Nevermind! La réponse était juste en face de moi, je n'ai tout simplement pas eu la bonne association.

def self.price 
    Available.minimum(:price, 
       :conditions => [ "price <> 0" ]) 
    end 

Cela fonctionne parfaitement après avoir utilisé

:has_many, :through => :model 

Je n'ai pas réalisé que je devais installer une relation plus complexe pour qu'il fonctionne correctement ...