2016-05-23 88 views
0

我正在从我的数据库中检索某些房间。房间属于酒店。我只收回属于距离所需区域很近(20公里)的酒店的房间,我也在检查房间是否有合适的容量。这使我有一套房间(有时每个酒店都有很多房间)。我只想渲染一个符合每个酒店标准的房间:最便宜的room_price。我怎样才能做到这一点 ?只为每家酒店提供价格最低的房间

这里是我的方法看起来像到目前为止

def find_hotels 
    # hotels near query 
    @hotels = Hotel.near(params[:place], 20) 
    number_of_people = params[:adults_number].to_i + params[:children_number].to_i 
    # rooms with the right capaciy 
    # rooms with the best price 
    @rooms = Room.where(hotel_id: @hotels.map(&:id)).where("capacity >= :number_of_people", {number_of_people: number_of_people}) 
    end 

回答

0

这个怎么样?

def find_hotels 
    # hotels near query 
    @hotels = Hotel.near(params[:place], 20) 
    number_of_people = params[:adults_number].to_i + params[:children_number].to_i 
    # rooms with the right capaciy 
    # rooms with the best price 
    list_of_rooms = @hotels.inject({}){|result, hotel| result[hotel.id] = cheapest_room_id(hotel.id, number_of_people); result} 
    end 

def cheapest_room_id(hotel_id, number_of_people) 
    return Room.where(hotel_id: hotel_id).where("capacity > ?", number_of_people).order("room_price ASC").first.id 
end 

变量list_of_rooms将包含一个散列以这种形式:

{ hotel_1 => room_123, hotel_2 => room_44, hotel_3 => room_666 } 

这里的一切是一个ID。 PS:它应该工作。

+1

这只是给你所有没有最便宜的房间最便宜的_room每家酒店... –

+0

@DavidGeismar对不起,看错你的问题。我更新了我的答案。 –

+0

find_by返回单个实例,但否则它运行良好,谢谢 –

1

我想你可能会认为在酒店里可能有不止一个房间的最低价格相等。

无论如何,如果你有100家酒店要考虑,那么你可能会发现每个酒店运行一个查询来找到最便宜的房间是不可接受的。

如果是这样,您可能需要深入SQL来优化搜索(并且还可以通过组合查询来查找酒店和查询来顺利查找房间)。

像这样的东西应该是高性能的。

def find_hotels 
    # hotels near query 
    number_of_people = params[:adults_number].to_i + params[:children_number].to_i 
    # rooms with the right capaciy 
    # rooms with the best price 
    @rooms = Room.where(hotel: Hotel.near(params[:place], 20)). 
       where("capacity >= :number_of_people", {number_of_people: number_of_people}). 
       where("not exists (select null 
            from rooms r2 
            where r2.hotel_id = rooms.hotel_id and 
              r2.capacity >= :number_of_people and 
              r2.room_price <= rooms.room_price and 
              r2.id   <= rooms.id)", , {number_of_people: number_of_people}) 
end 

它找到的房间,在所需的容量和更便宜的价格在同一家酒店没有另一个。事实上,假设您只希望每个酒店返回一个单人房间,情况会更进一步。

如果希望所有客房的最低费率返回,使用:

def find_hotels 
    # hotels near query 
    number_of_people = params[:adults_number].to_i + params[:children_number].to_i 
    # rooms with the right capaciy 
    # rooms with the best price 
    @rooms = Room.where(hotel: Hotel.near(params[:place], 20)). 
       where("capacity >= :number_of_people", {number_of_people: number_of_people}). 
       where("not exists (select null 
            from rooms r2 
            where r2.hotel_id = rooms.hotel_id and 
              r2.capacity >= :number_of_people and 
              r2.room_price < rooms.room_price)", , {number_of_people: number_of_people}) 
end 
+0

真棒查询技能。 ;) –

+1

@RareFever但是可以说尽管效率还不如它,但在合理的Rails-ey方法的约束下,ti可能会这样做。 :) –