Building an Event Booking App in Ruby with Macaw Framework: A Step-by-Step Guide
Tags: ruby, beginners, learning, webdev
Published: 2023-05-15 23:19:51

Hi There!

Today, I'm excited to walk you through building an Event Booking app using the [Macaw Framework](https://github.com/ariasdiniz/macaw_framework). This tutorial is perfect for beginners looking to learn the basics of web development with Ruby in a simple way. The full code of this example can be found [here](https://github.com/ariasdiniz/macaw_event_booking).

## Project Overview

Our Event Booking app has the following features:
1. User sign-up and login
2. Event creation
3. Booking of events

We're using SQLite for our database, and ActiveRecord as our ORM.

## Step 1: Setting up the project

Create a new directory for your project and initialize a new Gemfile by running `bundle init`. Make sure to include the following gems:

```ruby
gem 'macaw_framework'
gem 'active_record'
gem 'sqlite3'
gem 'yaml'
gem 'json'
```

Then, install your gems with `bundle install`.

## Step 2: Setting up the database

Next, we'll set up our SQLite database. For this project, we'll use an example SQLite database that's included in the repository:

```ruby
db_config = File.open('../db/database.yaml')
ActiveRecord::Base.establish_connection(YAML.safe_load(db_config, aliases: true))
```

## Step 3: Defining the Routes

We define routes for each of our features. We'll create separate modules for each set of related routes. For instance, here's how we define our routes for booking:

```ruby
def self.set_booking_routes(macaw)
  book_event(macaw)
  get_all_bookings(macaw)
end
```

In the `book_event` function, we define a POST route at '/bookings'. This route expects the client to send a JSON body with the name of the event to book. We'll parse this JSON, perform some validation, and then call our `BookingsHandler` to book the ticket:

```ruby
def self.book_event(macaw)
  macaw.post('/bookings') do |context|
    name = JSON.parse(context[:body])
    raise 'You must log in to book a concert' if context[:client].nil? || context[:client][:login].nil?
    raise 'The "name" of the event cannot be null.' if name.nil?

    BookingsHandler.book_ticket(context[:client], name['name'])
    return JSON.pretty_generate({ message: 'Event booked with success' }), 200, { 'Content-Type': 'application.json' }
  rescue StandardError => e
    return JSON.pretty_generate({ message: e.message }), 400, { 'Content-Type': 'application.json' }
  end
end
```

## Step 4: Implementing the Handlers

Each handler module is responsible for specific functionalities. For instance, the `ClientsHandler` module handles user sign-up and login.

Here's how we implement the signup process. We ensure that the request body contains a username and password, and then we hash the password before storing it in the database. If the client already exists, we raise an error:

```ruby
def self.signup(macaw)
  macaw.post('/signup') do |context|
    body = JSON.parse(context[:body])
    raise 'The request body must have username and password fields' if body.nil?
    raise 'The request body must have a username field' if body['username'].nil?
    raise 'The request body must have a password field' if body['password'].nil?

    ClientsHandler.signup(body)
    return JSON.pretty_generate({ message: 'Client registered' }), 201, { 'Content-Type': 'application/json' }
  rescue StandardError => e
    return JSON.pretty_generate({ message: e.message }), 400, { 'Content-Type': 'application/json' }
  end
end
```

## Step 5: Managing Sessions

Managing user sessions is a crucial part of any application. In our case, we're using the `session[:client]` to store our session data. For example, during the login process, we set `session[:client]` to the username of the logged-in user:

```ruby
def self.login(body, session)
  pswd = body['password']
  user = Clients.find_by(username: body['username'])
  raise 'User not found' if user.nil?
  raise 'Incorrect Password!' unless Digest::SHA2.hexdigest(pswd) == user.password

  session[:login] = user.username
```

## Conclusion

This is just a glimpse of how you can use Ruby with Macaw Framework to build an Event Booking app. There are many more features you can add, and I hope this guide gives you a good starting point. If you want to see the full application code, you can check out the [GitHub repository](https://github.com/ariasdiniz/macaw_event_booking).

Remember, the Macaw Framework is designed for simplicity and performance. It allows you to easily configure your web application with just a few lines of code, without the necessity of learning a Domain Specific Language (DSL). 

Happy coding!