Building Library App with Ruby on Rails

//
5 min readMar 12, 2021

--

Library is a complete Ruby on Rails application content management system (CMS) that manages data through complex forms and RESTFUL routes.

The repository for Library is here.

Has_many/Belongs_to/Has_many :through

The associations in Library App are as follows: a book has many ratings and a rating belongs to a user. A user has many books through ratings and a book has many users through ratings.

The many to many relationship is between the user having many books through ratings and the book having many users through ratings.

My join table is through ratings, which has two user submittable attributes, number, and comment. A user-submitted attribute is an attribute other than its foreign keys that can be submitted by the app's users.

Model Validations

Validations are used to ensure that only valid data is saved into your database. There are several ways to validate data before it is saved into your database, including native database constraints, client-side validations, controller level validations, and model-level validations.

Model-level validations are the best way to ensure that only valid data is saved into your database because they are database agnostic, cannot be bypassed by end-users, and are convenient to test and maintain.

We can validate using reader and writer methods, such as when we use password digest in our database.

The validations I included in my project were that in User, the username is present and unique and the email was present and unique, in Rating, the number and comment were both present, and in Book, the title was unique and the present and the author was present.

The following methods trigger validations, and will save the object to the database only if the object is valid:

  • create
  • create!
  • save
  • save!
  • update
  • update_attributes
  • Update_attributes!

The bang versions (e.g. save!) raise an exception if the record is invalid.

Validation errors and messages should be used when possible to notify the user that a validation error occurred.

Scope Method

For this project, it was a requirement that our models include at least one class level ActiveRecord scope method. The scope method must be chainable, which means we must use ActiveRecord Query methods within it (such as .where or .order) instead of native ruby methods (.find_all or .sort).

For my project, I used the scope method ordered by number which I built to put the highest rating first, and the lowest rating last.

Standard User Authentication & Omniauth

One part of the project requirement was to provide standard user authentication, including signup, login, logout and passwords. The authentication system also is to allow login from another service. In my project, I used OmniAuth to provide authentication to Google.

Request/Response Flow

Request/response flow is the action within a request/response cycle. A request/response cycle traces how a user’s request flows through the app. The steps are as follows:

  1. A user opens their browser, types a URL and presses Enter. This makes a request for that URL.
  2. The request hits the Rails router (config/routes.rb). The router maps to the URl to the correct controller and action to handle the request.
  3. The action receives the request and passes it on to the view
  4. The view renders the page as HTML.
  5. The controller sends the HTML back to the browser. The page loads and the user sees it.

Authentication

Authentication are important to the security of our app. The goal is to secure the app by making sure the user is who they say they are. We can use the gem bcrypt to ensure that plain text passwords are not saved in our database, so that non authenticated users cannot access this information.

In my app, I implemented authentication by using: Has secure password, omniauth, sessions controller, cookies, login required, before action require login.

ActiveRecord Associations

An association is a connection between two Active Record models. The types of associations are:

Migrations and the Schema file

Migrations are a way for you to alter your database in a structured and organized way. The schema file is the authoritative source for your database schema. The schema should not be edited. Schema files are also useful if you want a quick look at what attributes an Active Record object has.

Nested routes

Nested routes allow you to capture the nested relationship in your routing. A nested route is a type of nested resource. Nested resources are resources that are logically children of other resources. In this project, you must create and make use of a nested resource with the appropriate Restful URLs, You must include a nested new route with a form that relates to the parent resource. You must include a nested index or show route.

Scope methods

Scopes are custom queries that you define inside your Rails models with the scope method. Scoping allows you to specify your own commonly-used queries which can be referenced as method calls on the associated objects or models. Every scope takes two arguments, a name, which you use to call this scope in the code, and lamda, which implements the query.

Partials (Partial Templates)

Partial templates are used for breaking the rendering process into more manageable chunks. According to Ruby on Rails guide with partials, you can move the code for rendering a particular piece of a response to its own file. Partials are view-level files that only form one part of an HTML page.

To render a partial as part of a view, you can use the render method in the view.

<%= render “menu” %> which will render a file names _menu.html.erb.

To indicate that this file is partial, and only part of a larger view, we use an underscore as a prefix.

Rails filters (Before actions)

Filters are methods that are run before, after, or around a controller. Filters are inherited so if you set a filter on the application controller, it will be run on every controller in your application. Before filters are made by the before_action. They can halt the request cycle. A common “before” filter is one that requires that a user is logged in for an action to be run. The only option of before_action defines one action OR a list of actions when the method/block will be executed first. In this example,

before_action :set_newsletter_email, only: [:show, :edit, :update, :destroy]

The set newsletter method will be called before the show, edit, update and destroy methods. Except does the opposite.

What is the difference between <% %> and <%= %>?

The first one evaluates (just%) and second one evaluates and displays (<%=).(returns a value to a page).

What is the different between a helper method and a private method?

A helper is a method that is mostly used in your Rails view to share reusable code.

Private methods can be considered internal helpers method. Private methods are for internal usage within a defining class.

What does the exclamation point do in :authenticate_user!

The exclamation point means that it will modify the original variable vs returning a new string with the characters reversed.

--

--