Sinatra&Active Record
Published: 2022-02-12 22:56:08

For my 2nd project at Flatiron school I had to create an app using Sinatra and active record. I started with mapping out the project I wanted to create, one of the main requirements for this project was to set up an authentication for a user using the Bcrypt gem. That was a place to start! I needed to create the ability for a user to login & sign up. 

After having an idea of creating a tattoo artist online portfolio for this project, I created my project folder and sub-folders.
I ran bundle init in the command line which created a Gemfile where i added the gems I would need for this project.
Gemfile

`source 'http://rubygems.org'
gem 'sinatra'
gem 'activerecord', '~> 6.0.1', :require => 'active_record'
gem 'sinatra-activerecord', :require => 'sinatra/activerecord'
gem 'rake'
gem 'require_all'
gem 'sqlite3'
gem 'thin'
gem 'shotgun'
gem 'pry'
gem "tux"
gem "bcrypt", "~> 3.1"

group :test do
 
  gem 'rspec'
  gem 'capybara'
  gem 'rack-test'
  gem 'database_cleaner'
end`


I then needed to create the config folder and environment file.
This is a very important file; it's where your database connection is made and will connect your app folder with the rest of the files that require it.
When I initially set this up I had an error of my database/environment not being configured. I spent some time searching for answers which lead  me to learn that I had to set and specify my database.

`ENV['SINATRA_ENV'] ||= "development"

require 'bundler/setup'
require 'capybara/dsl'
Bundler.require(:default, ENV['SINATRA_ENV'])


set :database, {adapter: "sqlite3", database: "development.db"} 
require_all 'app'`


In the config.ru is where I loaded the environment and mounted the application controller. As my app grew I would include the other controllers here as well.

config.ru

`require_relative './config/environment'
if ActiveRecord::Migrator.needs_migration?
raise 'Migrations are pending. Run `rake db:migrate` to resolve the issue.'
end
use Rack::MethodOverride
run ApplicationController`


In app/controllers folder I created an application_controller.rb file

`class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views' enable :sessions
set :session_secret, 'password_security'
end

get '/' do
'Hello, World!'
end`

from here I could run shotgun and the browser at the local host address was up and running!

Since I needed to use activerecord, I set up my Rakefile.
this specified tasks and actions I would need, I loaded the environment and required 'sinatra/activerecord/rake'. 
Rakefile
`require_relative './config/environment'
require 'sinatra/activerecord/rake'`

 From there I added my Models for the corresponding database table, it will inherit from the ActiveRecord::Base class, which means that it has access to a number of methods for working with the database.

`class User < ActiveRecord::Base
has_secure_password 
has_many :tattoos
end`

has_secure_password is specified so i could set up authentication with Bcrypt. 

I then create a Database folder (db) and ran migrations to create a users tables.

I had to type `rake db:create_migration NAME=create_users`, to create the table and populate it with my columns, then run rake db:migrate for all of this to create a schema file.Then rake:create to create the database for my app.

user table

`class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :username
      t.string :password_digest
      t.timestamps null: false
    end
  end
end`
  From here I had to also create a tattoos table and controller and model. This was wall generally set up the same way as the user.
 I then moved onto my views and started with the users to create a sign up/login page which I would then in my users_controller use to correlate to the appropriate CRUD action. 
users_controller.rb
`class UsersController < ApplicationController

    get "/signup" do
        erb :"users/new"
    end 

    post "/signup" do
        user = User.new(params[:user])
        if user.save
            session[:user_id] = user.id 
            redirect "/users/#{user.id}"
        else 
            @errors = user.errors.full_messages.join(" - ")
            erb :'/users/new'
        end
    end

    get "/login" do
        erb :"users/login"
    end 

    post "/login" do
        user = User.find_by(username: params[:user][:username])
        if user && user.authenticate(params[:user][:password])
            session[:user_id] = user.id 
            redirect "/users/#{user.id}"
        else 
            redirect "/login"
        end
    end

    get "/users/:id" do
        @user = User.find_by(id: params[:id])
        erb :"/users/show"
    end 

    get "/logout" do
        session.clear
        redirect '/'
    end 

end ` 

 After all of this logic was set up I again followed the same process for setting up the tattoos MVC.  
The set up of this project was perhaps the most challenging and yet most simple! Its rather straight forward but it takes working out set by step in each folder to fully understand what you need to specify for the database and how it all works together. This project was certainly a great stepping stone in my knowledge as  developer.