Search code examples
sqlrubyweb-applicationshanami

implement a booking lock for users in a scheduling app


I've built a scheduling web app where users can book a conference for a given date and time slot on that date.

Now I need to implement a booking lock, which means that the admin can apply this lock and users can no longer book from that time on.

My current design includes a model booking_lock that only has one attribute of "status" with values of "On" and "Off".

The model would have only one record in the database at any given time as its sole responsibility would be to provide the data to check if booking has been locked.

---------------------EDIT-----------------------------------

This is not meant to lock individual records (conferences). To do this I use the attribute of user_id. If that is 0, then the conference is available for booking.

What I want to do now is disable (lock) the booking entirely before the user hits the database.

For example:

When a user logs on they see a notification saying the booking is locked. Also, they wouldn't see a respective button to book a conference and if by chance they would navigate to the respective URL they would be redirected to home page with the same notice as above. I've got all this covered.

But I need a general switch to be turned on and off and be the basis for this kind of check. Hence the booking_lock model.

Note: I use hanami-model.

---------------------EDIT-----------------------------------

My question is twofold:

  1. Is there a better way of implementing such a lock?
  2. How to ensure there is only one record in the db for such lock?

Solution

  • 1. Is there a better way of implementing such a lock?

    It seems that your requirement is to have an application-wide setting, which is best done with

    • An environment variable
    • A value stored in database

    Environment variables:

    • pros: system already in place, simple usage, can easily be configured statically and changed dynamically
    • cons: might be difficult to maintain with a multi-tenant architecture (multiple servers running the same app)

    DB persistence

    • pros: scales easily with a multi-tenant architecture
    • cons: can seem a bit of an overkill for one setting BUT can easily be abstracted into a Key/Value store for multiple settings.

    Example:

    Create an AppSettings model with two columns: key & value.

    Create and save an AppSetting with key "lock_booking_for_parents" and change the value through an admin interface.

    Access this AppSetting throughout the app to know if you should lock booking or not.

    Also, if you are worried about querying your database everytime you need to know if booking is enabled/disabled, you can easily implement caching.

    2. How to ensure there is only one record in the db for such lock?

    Environment variable

    Not applicable

    DB persistence

    You can create a helper class to access your settings with default behavior, and use first_or_create method to ensure the record is unique.

    class AppSettingsHelper
    
        def self.booking_enable?
          app_setting_record = AppSettings.find_by_key("lock_booking_for_parents")
          if app_setting_record 
            return app_setting_record.value
          else 
            ## default behavior of your app when no record has been created yet
            return true
          end
        end
        
        def self.enable_booking
          AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: false})
        end
        
        def self.disable_booking
          AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: true})
        end  
    end