APPlan — — Sinatra Web App

Hatice Karatay
4 min readApr 29, 2021

APPlan is a web app built for teachers to create and store their lesson plans. This Sinatra App is designed with MVC(Model, View, Controller) via CRUD(Create, Read, Update, Delete) methods using RESTful API. In this article, I will walk you through the step-by-step instructions for building models and how to use Bcrypt to secure passwords. Also, you can check the source code in my repo.

To build model classes and database migrations, the Active Record library is implemented. Active Record is an ORM. So what is an ORM? ORM(Object-Relational-Mapping) is a way of accessing a relational database using Object-Oriented language. To achieve this, database tables are mapped to classes, and their rows are mapped to objects of the classes. Instead of building individualized ORM methods, ActiveRecord’s built-in methods are used. Let’s see how many methods are available to us with Active Record.

Let’s begin by creating Models: Teacher and Plan.

 app
└── models
├── teacher.rb
└── plan.rb

Then create classes with no relations or ActiveRecord inheritance.

class Teacher
end
class Plan
end

In the Pry console, run Teacher. methods command to see how many methods are available:

pry(main)> Teacher.methods

This will give you an array of all methods :

pry(main)> Teacher.methods
=> [:yaml_tag,
:class_attribute,
:json_creatable?,
:allocate,
:superclass,
:new,
:descendants,
:subclasses,
:pretty_print_cycle,
:method_visibility,
:delegate_missing_to,
:included_modules,
:include?,
:name,
:ancestors,
:attr,
:attr_reader,
:attr_writer,
:attr_accessor,
:instance_methods,
:public_instance_methods,.... ]

And the list goes on. To find out how many methods are available, run the following command in your pry console:

pry(main)> Teacher.methods.count
=> 171

This is a lot. But let’s see how many methods are available after the inheritance :

class Teacher < ActiveRecord::Base
end
class Plan < ActiveRecord::Base
end

In pry console:

pry(main)> Teacher.methods.count=> 629

The number goes up to 629. So are we done? Is this all you need to set your models? Not quite. It’s now time to set our one-to-many relationship among model classes. A teacher has many lesson plans, and a lesson plan belongs to a teacher. The following macros handles this relationship:

class Teacher < ActiveRecord::Base
has_many :plans
end
class Plan < ActiveRecord::Base
belongs_to :teacher
end

This association provides more methods available in the active record.

pry(main)> Teacher.methods.count
=> 641

Now we know that Active Record does its magic and passes all these methods for us to call on objects we created; we need to create our databases to persist our objects in there. When we define an object, we define them with their attributes, if there are any. These attributes will not be defined in the models. Instead, we will set them as columns of our database tables. To do that, first, we need to create active record migrations.

rake db:create_migration NAME=create_teachers
rake db:create_migration NAME=create_plans

These commands will generate the following files with UTC timestamp.

db/migrate/YYYYMMDDHHSS_create_teachers.rb

db/migrate/YYYYMMDDHHSS_create_plans.rb

Each of these files will be inherited from ActiveRecord::Migration with its specific versions. Let’s add our columns to tables:

class CreateTeachers < ActiveRecord::Migration[5.2]
def change
create_table :teachers do |t|
t.string :username
t.string :password_digest
end
end
end
class CreatePlans < ActiveRecord::Migration[5.2]
def change
create_table :plans do |t|
t.string :title
t.text :objective
t.string :vocabulary
t.integer :teacher_id
t.timestamps
end
end
end

Once migration classes are set, we can migrate them :

rake db:migrate

After a successful migration, a schema.rb will be formed in your db folder. This file displays the schema of the tables you created.

The plans table has a foreign key teacher_id. This key shows that a plan belongs to a teacher.

You might also be wondering why we store passwords as password_digest. The answer to this comes next:

To secure passwords via Bcrypty

  1. In your Gemfile, add gem ‘bcrypt’
  2. Install the gem via bundle install or gem install bcrypt
  3. To authenticate the user password, add the has_secure_password macro to your user class.
class Teacher< ActiveRecord::Base
has_many :plans
has_secure_password
end

4. In your teacher table, have a password_digest column in the string type

class CreateTeachers < ActiveRecord::Migration[5.2]
def change
create_table :teachers do |t|
t.string :username
t.string :password_digest
end
end
end

What happens here is that instead of storing the user's password directly, a salt, a random string character, is added to the user's password. Together the password and the salt goes into a hashing algorithm and are saved as a digested form password in the database.

5. When a user wants to log in, bcrypt uses the .authenticate method by taking the user's newly entered password as an argument and adding the salt to it so that together they go through a hashing algorithm. Finally, this newly digested password and the user's correct password_digest are compared. If both digested passwords are a match, then the result of this would be the object it was called on. Otherwise, it returns false.

These are steps of setting one-to-many relationships among two model classes. which is the simplest. For more complex or several relationships, Active record does its magic to do all the work for you after setting correct relationships among classes.

To learn more about Active Record associations, please refer to the Active Record Associations guide. For more info about Active Record Migrations, check this page.

Thanks

--

--