Hands-on with Sinatra Persistence

Database schema for a small bit of Twitter
Person(name, dob, gender, zipcode)
Hashtag(name)
Message(person_id, hashtag_id, comment)
Gemfile
source 'https://rubygems.org'

gem 'sinatra'
gem 'activerecord'
gem 'sinatra-activerecord'
gem 'pry-byebug'
gem 'rake'
gem 'byebug'
gem 'rack-test'
gem 'pg'

bundle install
Basic directory structure
demo_app/
  config/
    database.yml
  db/
    migrate/
      .
    schema.rb
  models/
    .
  views/
    .
  Gemfile
  Rakefile
  config.ru
  demo_app.rb
Config.ru
# Config.ru configures the interface between "Rack" and Sinatra

require './demo_app'
run Sinatra::Application
Rakefile
require './demo_app.rb'
require 'sinatra/activerecord/rake'
require 'rake/testtask'

Rake::TestTask.new do |t|
  t.pattern = "test/*_test.rb"
end
config/database.yml
# Create mapping from server "environment" (development|test|production) to database
development:
  adapter: postgresql
  encoding: unicode
  database: development
  pool: 2

production:
  adapter: postgresql
  encoding: unicode
  database: database_name
  pool: 2
  username: your_username
  password: your_password
demo_app.rb
require 'sinatra'
require 'sinatra/activerecord'
require 'pry-byebug'
Migration files
rake db:create_migration NAME=create_messages
rake db:create_migration NAME=create_hashtags
rake db:create_migration NAME=create_people

# Create people
class CreatePeople < ActiveRecord::Migration[5.1]
  def change
    create_table :people do |t|
      t.string :name
      t.date :dob
      t.string :gender
      t.integer :zipcode
    end
  end
end

# Create hashtags
class CreateHashtags < ActiveRecord::Migration[5.1]
  def change
    create_table :hashtags do |t|
      t.string :name
    end
  end
end

# # Create messages migration
class CreateMessages < ActiveRecord::Migration[5.1]
  def change
    create_table :messages do |t|
      t.integer :person_id
      t.integer :hashtag_id
      t.string :status
      t.string :text
    end
  end
end

rake db:migrate
Models
# models/hashtag.rb
class Event < ActiveRecord::Base
end

# models/person.rb
class Person < ActiveRecord::Base
end

# models/message.rb
class Message < ActiveRecord::Base
end

Seed the database, create seeds.rb

require_relative '../demo_app.rb'
puts "[seeds.rb]"
puts "[creating seed Persons]"
Person.create(name: "John", dob: '12-12-1980', gender: 'f', zipcode: 12355)
Person.create(name: "Angelo Smith", dob: '12-12-2000', gender: 'm', zipcode: 12355)
Person.create(name: "Jane", dob: '12-12-2018', gender: 'f', zipcode: 12355)
puts "Created #{Person.count} people"

puts "[creating seed Hashtags]"
Hashtag.create(name: "programming")
Hashtag.create(name: "recreation")
puts "Created #{Hashtag.count} hashtags"

puts "[create registrations]"
$ rake db:seed
Examining the databases from the Debugger
$ pry -r './demo_ap.rb'
ActiveRecord::Base.connection.tables
Person.all
Person.where(gender: 'm')
Person.where("dob > ?", Date.new(1995))
Person.where("dob > ?", Date.new(1995)).count
CRUD operations (Create, Read, Update, Delete)
p = Person.new(name: "Pito", dob: '12-12-2012', gender: 'f', zipcode: 12355)
p.new_record?
p.save
p = Person.create(name: "Amin", dob: '12-12-2014', gender: 'm', zipcode: 31231)
p.delete

Associations, declared in models
class Person < ActiveRecord::Base
  has_many :messages
  has_many :hashtags, through: :messages
end
class Hashtag < ActiveRecord::Base
  has_many :messages
  has_many :people, through: :messages
end
class Message < ActiveRecord::Base
  belongs_to :person
  belongs_to :hashtag
end
Association, used
Person.find(1).hashtags
Person.where(name: "Angelo Smith").first.messages
Event.find(1).people
Validations

Validations are applied by ActiveRecord, NOT the database

validates :zipcode, length: { is: 5}    # declared in model file
p = Person.find(1)
p.zipcode = 1                           # assign invalid value
p.valid?                                # explicit check
p.save                                  # Is not permitted into the database
p.save!                                 # Same but throws exception

Appendices

References