只为每家酒店提供最便宜的房间

时间:2016-05-23 14:26:49

标签: ruby-on-rails activerecord querying

我正在从我的数据库中检索某组房间。房间属于酒店。我只检索属于酒店的房间,距离要求的区域很近(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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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:它应该有用。