我已经创建了一个应用程序,用户可以预订车辆(小巴)我已经让应用程序在用户可以预订车辆的地方工作,但车辆不能预订。我有一个简单的搜索工作,允许用户搜索品牌或型号。我正在寻求扩展此搜索,以便用户可以搜索所有可用于用户想要预订的日期的车辆。我不太确定怎么接近这个可以请有人帮忙!
我有一张Vehicle表,User表和一张Reservation表。
我的架构看起来像(我只包括相关的表格):
create_table "reservations", force: :cascade do |t|
t.date "startDate"
t.date "endDate"
t.integer "noOfDays"
t.integer "costs"
t.integer "vehicle_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_reservations_on_user_id"
t.index ["vehicle_id"], name: "index_reservations_on_vehicle_id"
end
create_table "users", force: :cascade do |t|
t.string "address"
t.string "city"
t.date "dateofbirth"
t.string "email"
t.string "fname"
t.string "postcode"
t.string "sname"
t.string "user_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "contact_no"
end
create_table "vehicles", force: :cascade do |t|
t.string "description"
t.integer "door"
t.string "fuel"
t.string "img"
t.string "make"
t.string "model"
t.date "motEnd"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.date "motDue"
t.date "motStart"
t.integer "price"
t.string "reg"
t.integer "seats"
t.string "transmission"
t.date "year"
t.decimal "engine"
end
我已经得到了重叠预订,这与我使用的解决方案类似:Avoid double bookings for a minibus reservation system
我试图扩展我的搜索范围,以便用户可以在索引页面上的两个日期之间搜索所有可用车辆。我只是不知道我是如何让它工作的,所以系统会显示该日期的可用车辆。
我目前的简单搜索:
车辆控制器:
def vehicle_search
vehicles = Vehicle.fuzzy_search(params[:search_string])
@vehicles = Kaminari.paginate_array(vehicles.order :make).page(params[:page]).per(3)
if @vehicles.empty?
flash.now[:alert] = "No records found - displaying all records ..."
@vehicles = Vehicle.order(:make).page(params[:page]).per(3)
end
render :action => "index"
端
vehicle.rb
def self.fuzzy_search(search_string)
search_string ||= ""
make = search_string
model = search_string
price = search_string
fuel = search_string
transmission = search_string
self.where("make LIKE ? OR model LIKE ? OR price LIKE ? OR fuel LIKE ? OR transmission LIKE ?", make, model, price, fuel, transmission)
end
搜索部分
<%= form_tag my_path, :method => 'post', :multipart => true do %>
<!--vehicle details-->
<%= text_field_tag :search_string, "", class: 'form-control custom2' %>
<%= submit_tag 'Search', class: "btn btn-default" %>
<% end %>
辆/ index.html.erb
<a>Make, Model, Fuel Type, Transmission: </a>
<%= render(:partial=>'/vehicle_search',:locals=> { :my_path => "/vehicles/vehicle_search" })%>
答案 0 :(得分:1)
我将使用以下逻辑来确定时间重叠:
(StartA&lt; = EndB)和(EndA&gt; = StartB)
如果以上是true
,则期间重叠。您可以在Stack Overflow问题中查看:Determine Whether Two Date Ranges Overlap
因此,让我们在预订时创建两个范围。一个用于获得与一个时间点重叠的重叠预留,一个用于获得与时间窗口重叠的重叠预留。
class Reservation < ApplicationRecord
# code ...
# assuming Reservation has start_time and end_time attributes
# and you validate that start_time is always before end_time
# time param can also be a date or datetime
def self.overlap(time)
# Reservation start_time is less than or equal to the given time
# and reservation end_time is greater than or equal to the given
# time.
where(arel_table[:start_time].lteq(time))
.where(arel_table[:end_time].gteq(time))
end
def self.overlap_window(start_time, end_time)
# Reservation start_time is less than or equal to the given
# end_time and reservation end_time is greater than or equal
# to the given start_time.
where(arel_table[:start_time].lteq(end_time))
.where(arel_table[:end_time].gteq(start_time))
end
# code ...
end
现在,您可以通过检查哪些车辆未被占用(例如某个时间窗口)来轻松获取车辆。
Vehicle.where.not(id: Reservation.select(:vehicle_id).overlap_window(Time.now, 4.hours.from_now))
注意:开始时间必须始终在结束时间之前(对于预订和时间窗口),这可以按照在日期重叠问题中解释的(主要在注释中)解释一开始。