只渲染每个酒店价格最低的房间

Only render rooms with the cheapest price for each hotel

我正在从我的数据库中检索一组特定的房间。一个房间belongs_to一个酒店。我只检索属于靠近请求区域(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

这个呢?

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:应该可以。

我猜你可能会考虑酒店可能会有不止一间最低价相同的房间。

无论如何,如果您要考虑 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