I thought Sinatra was just a singer...?
Tags: ruby, rails, webdev
Published: 2022-07-11 23:52:43

## Who (or what) is Sinatra? ##

When I first started learning about Ruby, I heard the word Sinatra thrown around a lot. And when I heard it, all I hear was Frank Sinatra's 'My Way' ringing in my ear. What does Frank Sinatra have to do with Ruby, or even coding? Even when I started learning about it in the context of Ruby, I still had a hard time understanding it, so I devoted some time to understanding it more thoroughly. Now, I'd like to share with others what I've learned because Sinatra is pretty cool!

Essentially, Sinatra is a DSL, or domain-specific language, that allows you to create a mock frontend web application with using just Ruby and libraries developed from Ruby (e.g., ActiveRecord). I've been told by my instructors as Flatiron School that Sinatra is like training wheels for Ruby on Rails. Ruby on Rails is a powerful framework for development that provides the user with ample code and resources to create an efficient and powerful application. Sinatra, with much less code and an easier set up, makes web development possible for Ruby beginners. 

## How do you set up Sinatra? ##

A fellow Flatiron student has a blog post that thoroughly describes the steps to set up Sinatra [here](https://flatironschool.com/blog/how-to-build-a-sinatra-web-app-in-10-steps/). But some things have changed! So, I will provide a more up-to-date version here. 

1). Create a config file with both a database.yml and environment.rb file. 

database.yml: 
```
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3
```
This ensures that you can link your files to a database.

Environment.rb file:
```
ENV['RACK_ENV'] ||= "development"

require 'bundler/setup'
Bundler.require(:default, ENV['RACK_ENV'])

require_all 'app'
```
This connects your app folder with your models and controller to the rest of your files. Both of these are necessary for Sinatra to function. 

2). Ensure that you have the correct gems in your gemfile.

Here are the gems you will need to install, among others of your choice:

```
source "https://rubygems.org"

gem "sinatra", "~> 2.1"

gem "thin", "~> 1.8"

gem "rack-contrib", "~> 2.3"

gem "rack-cors", "~> 1.1"

gem "activerecord", "~> 6.1"

gem "sinatra-activerecord", "~> 2.0"

gem "rake", "~> 13.0"

gem "sqlite3", "~> 1.4"

gem "require_all", "~> 3.0"

group :development do
  gem "pry", "~> 0.14.1"
  gem "rerun"
end
```

3). Create the config.ru file.

This file is what allows you to use the application controller, which functions as the intermediary between your frontend code and your ruby code. It is essential to have this file.

```
require_relative "./config/environment"

use Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :delete, :put, :patch, :options, :head]
  end
end

use Rack::JSONBodyParser

run ApplicationController ## Most critical yet forgotten line!
```
4). Create an application controller. 

This is a file that should be created in your app/controllers folder. It looks similar to a regular model, but with some important differences. 

```
class ApplicationController < Sinatra::Base
  set :default_content_type, 'application/json'
  
  get "/" do
     { message: "I love Frank Sinatra!" }.to_json
  end

  get "/games" do
     Game.all.to_json
  end
end
```
After this, if you were to run `bundle exec rake server`, you would be led to http://localhost9292 and there find the message I've written above in json! If we were to go to http://localhost9292/games, we would see an array of all the `game` objects written in json!

If you're familiar with Javascript and React, you know that in order to get any sort of information from a website, you need to make a fetch request. When we make such requests, we use a URL that has our data (like localhost). For example:

```
useEffect(() => {
    fetch("http://localhost:9292/games")
      .then((r) => r.json())
      .then((data) => setGames(data));
  }, []);
```

What we've essentially done is set up our own link that we can then call upon in a fetch request. Instead of finding a server with data, we can make our own!

What we can also now do is create any sort of link in our controller folder that can summon any portion of our data using Ruby and ActiveRecord. Do we just want to render one instance of a particular model? Or do we want to render the first 10 of another? The beauty of using Sinatra in this way is that we can easily gather this information and send it to our frontend in a way that doesn't require us a lot of effort. 

So, not only is Sinatra a fantastic singer, but it's also a handy tool that we as Ruby beginners can prepare ourselves for Ruby on Rails!

## Sources ##
- http://sinatrarb.com/intro.html
- https://www.netguru.com/blog/ruby-versus-ruby-on-rails#:~:text=Ruby%20is%20an%20open%20source,for%20its%20use%20and%20application
- https://webapps-for-beginners.rubymonstas.org/sinatra/sinatra_rails.html#:~:text=Sinatra%20is%20much%20more%20lightweight,know%20how%20to%20use%20it
- https://flatironschool.com/blog/how-to-build-a-sinatra-web-app-in-10-steps/