Skip to content

Instantly share code, notes, and snippets.

@DeepNeuralAI
Last active April 4, 2019 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeepNeuralAI/efd2f56b798fef9d38ad90a277d7cbfb to your computer and use it in GitHub Desktop.
Save DeepNeuralAI/efd2f56b798fef9d38ad90a277d7cbfb to your computer and use it in GitHub Desktop.
Sinatra MVC Demo

Active Record - Key Points

Written by: Aaron J. Mendonsa

In this demo, we will be using SQLite as the default database. In order to understand the backend better, and therefore, create a richer application, we first need to define some terms.

Create Read Update Delete (CRUD)

CRUD

Migrations

Ruby code that lets you modify the database.

For example:

  • Create Tables
  • Change columns
  • Adding attributes
  • Deleting models

You can create migrations and apply them to the database, changing the database state. This allows you to roll back to previous migrations, allowing your database and application to be very flexible.

In summary, migrations are for database schema.

Once a migration or modification is made, it needs to be applied to the database in order to "migrate" the DB to a new state.

Running rake db:migrate applies all migrations in the db/migrate folder in timestamp order.

Active Record

Interacting with the Database data

Source: Active Record - Rails

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic.

For example:

  • Inserting rows in the database
  • Removing the rows from the database
  • Updating rows
  • Deleting

Recall in the SQL lectures, we primarily used an RDBMS or Relational Database Management System. In that type of database system, the models were treated as tables that had associations with other tables.

Active Record takes the framework of an RDBMS and treats each model as an object, allowing you to seamlessly treat a model as a Ruby object. Now, you are able to create, retrieve,update, and delete objects without any query language to the database.

In simple terms: we abstract the nuances of databases to objects.

RDBMS => ORM

Using ORM, the properties and relationships of the objects in an application can be easily stored and retrieved from a database **without writing SQL statements directly and with less overall database access code.**

Database Independence

Instead of specifying the domain of each attribute, for example int or text or bigint in MySQL or PostgreSQL, we just have to specify the standard domains.

For example, here is how the mapping works:

Data Type Mapping

We now can focus on these data types without worrying about memory management, or specific data types.

Source: What each data type does

You might also find it useful to know generally what these data types are used for:

  :string - is for small data types such as a title. 

  :text - is for longer pieces of textual data, such as a paragraph of information

  :binary - is for storing data such as images, audio, or movies.

  :boolean - is for storing true or false values.

  :date - store only the date

  :datetime - store the date and time into a column.

  :time - is for time only

  :timestamp - for storing date and time into a column.

  :decimal - is for decimals 

  :float - is for decimals. 

  :integer - is for whole numbers.

  :primary_key - unique key that can uniquely identify each row in a table

Creating Tables with Migrations

By convention, table names are always plural.

So, in this example, the model Restaurant would relate to the table Restaurants.

  • An id column is automatically created and used as a primary key

  • timestamps method creates created_at and updated_at columns.

To create a table for an model:

rake db:create_migration NAME=create_users

OR 

rake db:create_migration NAME=create_restaurant

This will then generate a migration file in the db/migrate folder, ready for editing.

It could look something like this:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
    end
  end
end

We can then edit our migration file, adding in appropriate attributes. After adding attributes, we then run a migration, to apply the changes to the database.

rake db:migrate

We can see an example here of it running our migration: image

Editing Our Migrations

Adding/Removing Column Adding:

add_column :table_name, :column_name, :column_type

Removing:

remove_column :table_name, :column_name

Example:

# Starting Migration
class CreateRestaurant < ActiveRecord::Migration[5.2]
  def change
    create_table :restaurants do |t|
      t.string :name
      t.string :address
      t.string :food_type
      t.string :description
      t.string :review
      
      t.timestamps
    end
  end
end

image

class RemoveAddressFromRestaurants < ActiveRecord::Migration[5.2]
  def change
    remove_column :restaurants, :address
  end
end
class AddAddressFromRestaurants < ActiveRecord::Migration[5.2]
  def change
    add_column :restaurants, :address, :string
  end
end

Seeding Data (the fun part)

In our folder structure, we have a seeds.rb file located at db/seeds.rb that we can add or seed data. Faker is a great resource here to avoid manually typing in data.

Once your seed file is complete, we run rake db:seed

In this case, I've created 20 restaurants with various fake attributes.

puts "Destroying old data"
Restaurant.destroy_all

puts "Start of Seeding..."
20.times do
  params = {
    name: Faker::Restaurant.name,
    address: Faker::TvShows::RickAndMorty.location,
    food_type: Faker::Restaurant.type,
    review: Faker::Restaurant.review  
  }
  puts "Creating Restaurant: #{params[:name]}"
  restaurant = Restaurant.new(params)
  restaurant.save
end

puts "Seeding Over"

Other Useful DB commands

Type rake -T for a full list of commands.

# Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)
rake db:create  

# Create a migration (parameters: NAME, VERSION)
rake db:create_migration 

# Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)
rake db:drop 

# Load fixtures into the current environment's database
rake db:fixtures:load 

# Migrate the database (options: VERSION=x, VERBOSE=false)
rake db:migrate 

# Display status of migrations
rake db:migrate:status    

# Rolls the schema back to the previous version (specify steps w/ STEP=n)
rake db:rollback

# Create a db/schema.rb file that can be portably used against any DB supported by AR
rake db:schema:dump

# Load a schema.rb file into the database
rake db:schema:load

# Load the seed data from db/seeds.rb
rake db:seed

# Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)       
rake db:setup

# Dump the database structure to db/structure.sql
rake db:structure:dump

# Retrieves the current schema version number
rake db:version           

Demo Specific Misc Info

Bootstrap

Bootstrap

Attach the following link in the HEAD of your HTML page (in this case layout.erb)

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

In order to apply Bootstrap styling to our app, we need to make sure we follow the naming requirements from the docs. For example:

image

Sharing Common Components

Imagine we have a navbar on every page, it would be tedious and repetitive to have to paste the exact same code on every erb file.

In order to avoid this, we can use yield.

Understanding yield Within the context of a layout, yield identifies a section where content from the view should be inserted.

The simplest way to use this is to have a single yield, into which the entire contents of the view currently being rendered is inserted:

<html>
  <head>
  </head>
  <body>
  <%= yield %>
  </body>
</html>

Adding a navbar to every page

<html>
  <head>
  </head>
  <body>
  <div class="navbar">
    # Navbar code here
  </div>
  <%= yield %>
  </body>
</html>

We can further organize the navbar code in another file, called navbar.erb

<!doctype html>
<html lang="en">
  <head>
      <meta charset="utf-8">
      <title>feedsy</title>
      <meta name="description" content="feedsy">
      <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      <link rel="stylesheet" type="text/css" href="<%= url('stylesheets/styles.css') %>">         
  </head> 
  <body>
    <%= erb :'layouts/navbar' %>
    <%= yield %>
  </body>
</html>

Sinatra Quirks

Editing and Deleting is weird in Sinatra. Follow these general guidelines:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment