【发布时间】:2015-09-08 08:51:38
【问题描述】:
我正在其他人设置的应用上实现基本搜索功能。有 3 个表 Booking、Room 和 Host,搜索功能需要向用户询问 3 个字段:start_date、end_date 和 number_of_guests。
搜索需要返回在该时间段内有可用房间的房东列表(start_date/end_date 参数)以及同一房间内的客人数量,显示在该时间段内该房东有哪些房间可用,如果有的话的房间已经有客人预订了。
搜索还需要根据他们现有的预订(列在Bookings 表中)确定哪些房东有空,并且需要显示所有有空房的房东,即使房间已部分预订。
我当前的解决方案如下所示。在app/views/search/new.html.erb:
<div class="row search-area">
<%= form_tag search_index_path, method: :get do %>
<div class="small-12 medium-1 large-1 columns search-field">
<%= label_tag "From", nil, class: "right inline" %>
</div>
<div class="small-12 medium-2 large-2 columns search-field">
<%= text_field_tag(:start_date, params[:start_date]) %>
</div>
<div class="small-12 medium-1 large-1 columns search-field">
<%= label_tag "To", nil, class: "right inline" %>
</div>
<div class="small-12 medium-2 large-2 columns search-field">
<%= text_field_tag(:end_date, params[:end_date]) %>
</div>
<div class="small-12 medium-1 large-1 columns search-field">
<%= label_tag "Guests", nil, class: "right inline" %>
</div>
<div class="small-12 medium-2 large-2 columns search-field">
<%= number_field(:number_of_guests, params[:number_of_guests], in: 1.0..20.0, step: 1.0) %>
</div>
<div class="small-12 medium-3 large-3 columns">
<%= submit_tag "Search", name: nil, :class => "button" %>
</div>
<% end %>
</div>
在search_controller.rb:
def index
@start_date = Date.parse(params[:start_date])
@end_date = Date.parse(params[:end_date])
@guests = (params[:number_of_guests]).first.to_i
@space = 0
@bookings = Booking.all
@hosts = [] # this will store available hosts
# get all hosts for specified time period
@bookings.each { |b| @hosts.push(b.room.host) if ((b.start_date >= @start_date &&
b.start_date <= @end_date) || (b.end_date >= @start_date &&
b.end_date <= @end_date)) }
@hosts = @hosts.paginate(page: params[:page], per_page: 5)
end
在app/views/search/index.html.erb:
<div>
<% @hosts.each do |host| %>
<div class="row">
<% if host.rooms.any? { |room| room.bookings.empty? } %>
<!-- if a host has rooms without bookings then they are definitely going to have free rooms -->
<div class="small-3 medium-4 large-4 columns">
<%= image_tag host.picture_url %>
</div>
<div class="small-9 medium-8 large-8 columns">
<p>Host #<%= host.id %>: <%= host.name %></p>
<p><%= host.address %></p>
<% host.rooms.each do |room| %>
<!-- display information on free rooms -->
<% if room.bookings.empty? %>
<p>room #<%= room.id %> is available (0 booked, <%= room.capacity %> free out of <%= room.capacity %>)</p>
<% else %>
<!-- for the rooms with bookings - check if rooms are fully booked first -->
<% unless ((room.capacity - room.bookings.first.number_of_guests) == 0) %>
<% total_booked = room.bookings.first.number_of_guests %>
<% space = room.capacity - total_booked %>
<p>room #<%= room.id %> is available (<%= total_booked %> booked, <%= space %> free out of <%= room.capacity %>)</p>
<% end %>
<% end %>
<% end %>
</div>
<% else %>
<!-- if all the rooms belonging to a host are booked - check if all the rooms are fully booked -->
<% if !(host.rooms.all? { |room| (room.capacity - room.bookings.first.number_of_guests) == 0 }) %>
<!-- If all the rooms are fully booked there is nothing to display so there is no else block. Check the rooms individually for availability -->
<div class="small-3 medium-4 large-4 columns">
<%= image_tag host.picture_url %>
</div>
<div class="small-9 medium-8 large-4 columns">
<p>Host #<%= host.id %>: <%= host.name %></p>
<p><%= host.address %></p>
<% host.rooms.each do |room| %>
<% unless ((room.capacity - room.bookings.first.number_of_guests) == 0) %>
<% total_booked = room.bookings.first.number_of_guests %>
<% space = room.capacity - total_booked %>
<p>room #<%= room.id %> is available (<%= total_booked %> booked, <%= space %> free out of <%= room.capacity %>)</p>
<% end %>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
</div>
我意识到这个解决方案存在很多问题,所以我想问是否有人可以为我指出正确的方向,我需要采取哪些步骤来使此代码符合最佳实践并提高性能/高效的。具体来说:
- 我知道为可用房间过滤主机的逻辑不应该在视图文件中,但我不确定如何将其移动到控制器,或者这是否是合适的位置。我正在分解将此代码放在其他地方的逻辑。
- 我没有搜索模型,因为我的理解是模型与数据库表相关联,而搜索功能没有。我这样想错了吗?
- 视图中有很多重复,我希望当我最终弄清楚逻辑过滤室/主机应该去哪里时,这已经被清除了,但如果没有任何关于干燥视图文件的提示?
- 我知道在计算每个房间的可用空间时 - 我只检查该房间的第一次预订。目前每个房间只有 1 个预订,但我知道它不会保持这种状态,实际上我应该检查该房间的所有预订。我没有这样做,因为它与我在根据 start/end_date 参数检索到可用的主机后如何进一步过滤主机的困惑有关。
任何帮助找出使这个更多的 rails/ruby-ist 和更高性能的步骤将不胜感激。
【问题讨论】:
标签: ruby-on-rails ruby