0

In my Ruby on Rails app, bike rental companies can manage all their bikes (reservations, payments etc.).

Context I would like to offer a bike rental companies (shops) the option to implement a booking form on their own website, so they can let customers make a reservation for a bike.

  • This booking form would then show bike_categories of which bikes are available for a given arrival and departure date.

Question After reading some documentation online, I think I should create a separate table to deal with the availability per bike_category, which would then show the the count of bikes available for the selected arrival and departure date.

=> example: between 1-1-2020 and 1-2-2010 20 bikes of bike_category "mountainbike" are available

But I'm unsure how the structure of the table should be, as a reservation is on a bike-level, which consequently belongs to a bike_category?

Code

models

class Shop < ApplicationRecord
  has_many :bike_categories, dependent: :destroy
  has_many :bikes, through: :bike_categories
  has_many :reservations, dependent: :destroy
end

class Reservation < ApplicationRecord
  belongs_to :shop
  belongs_to :bike
end

class Bike < ApplicationRecord
  belongs_to :bike_category
  has_many :reservations, dependent: :destroy
end

class BikeCategory < ApplicationRecord
  belongs_to :shop
  has_many :bikes, dependent: :destroy
end
techquestion
  • 489
  • 5
  • 20

1 Answers1

1

I personally wouldn't create another table for this. I would query the user for the dates they intend to rent the bikes. Once you have the start and end dates, i'd run a query on the reservation table to find which bikes are unavailable during this time.

E.g.

reserved_bikes = Reservation.distinct.pluck(:bike_id).where(start_time: Time.now..user_end_time, end_time: Time.now..user_start_time)

Then I'd use these to find out how many of each category there are

Bike.where.not(id: reserved_bikes).group(:category).count

There's probably a way to do the above with joins in one query too if you look into it.

Generally I avoid adding more tables when the data is already able to be inferred. The main reason being that if you update the original table (in this case reservations), you'll then have to cascade those updates to the "inferred data" tables which is a mess to maintain.

gdxn96
  • 369
  • 5
  • 16
  • Thanks for your input, but in order to create a RESTful API, I need to create this table such that I can share the number of ```bikes``` available for a certain ```bike_type```. Correct? – techquestion Jan 28 '20 at 16:45
  • A custom search endpoint for complex business logic is accepted in REST. For example, the start_date, end_date, and category could be passed as http params, to an `available_bikes` "resource", without having to create a corresponding table in the database. Rest does not require the resource to be a standalone table. Check out this answer for another explanation. https://stackoverflow.com/a/31984477/37083 If sharing the available bikes is important, it would be better to share the link to rerun the query rather than creating a resource, as it could be out of date by the time you view it – gdxn96 Jan 28 '20 at 17:30
  • Wow thanks @gdxn96! I learned something new thanks to your answer. Keep up the good work! – techquestion Jan 28 '20 at 17:51