Easy Notification System in Rails Part 3

Read part 1 and part 2 of this series

In this post, we will be sending automatic e-emails every time notifications are created.

Creating the Mailer

We will work with one mailer that will send e-mails for every notification that is created. We can generate our mailer with this command:

rails g mailer NotificationsMailer

Our mailer will contain an action for each notifiable type that works with notifications in our application. In this series, we've been using comments and posts as examples.

Read more…

Easy Notification System in Rails Part 2

Read Part 1 of this series here

In Part 1 we learned how to setup our models and controllers to create notifications using callbacks in our application. Then we displayed these notifications in a Bootstrap 3 navbar using JQuery written in CoffeeScript.

In this post we will be adding more functionality to our notification system.s

Mark as Read Feature

We will be adding a feature that allows the current user to mark a notification as read as well as all notifications, in the following manner:

  • For a single notification, it should be marked as read when it is clicked from the list of notifications.
  • For all notifications, they should be marked as read when a specific button is pressed.

Setting up the Routes

Let's begin adding the necessary routes. In part 1 we defined a notifications resource. We will add a collection POST route and a member POST route of the same name:

# config/routes.rb
Rails.application.routes.draw do
  # ...

  resources :notifications, only: [:index] do
    post :mark_as_read, on: :collection
    post :mark_as_read, on: :member


Read more…

Easy Notification System in Rails

Having a notification system is very common for a web application. In this post I will go over how to implement your own simple and easy notification system for your Rails application.

This post is heavily inspired by Chris Oliver's In-App Navbar Notifications tutorial, with a few personal changes and additions.

Read part 2 of this series.

Models and Routes

Before starting with the models, lets quickly define the application resources in our routes:

# config/routes.rb
Rails.application.routes.draw do

  devise_for :users

  resources :posts do
    resources :comments

  resources :notifications, only: [:index]


The Notification Model

We will manually generate the notification model which will handle the storing of notifications in the database. We can generate a very basic model like this:

rails g model Notification recipient_id:integer actor_id:integer read_at:datetime action:string notifiable_id:integer notifiable_type:string

Here is an explanation for some of the fields for the above model:

  • recipient_id: Represents the user in your application which will receive the notification.
  • actor_id: Represents the user in your application which triggered the notification.
  • read_at: The time when the notification was read. A value of nil is used for unread notifications.
  • notifiable_id: The object that represents this notification (a post, comment, etc). This will be a polymorphic association.
  • notifiable_type: Type of the notifiable object. This is usually represented by a humanized (and optionally, internationalized) string form of the object's class.

Read more…

Integrating Devise With Rolify in Rails

I have searched through tons of StackOverflow questions and blog posts on how to properly integrate Rolify with Devise when registering as a new user through the registration view provided by Devise. All proposed solutions and half-solutions seemed very messy to me, but I found a very simple way to achieve this.

Preparing the Roles

Assuming you already have initialized a Devise User model along with a Rolify Role model, a very common question I see is how should the roles be prepared so that the new users can have a list of already created roles to choose from when registering? In the Rolify documentation, most (if not all) examples involve implicitely creating roles by adding roles to user in the Rails console:

user = User.find(1)
user.add_role :admin

A new admin role will be created if it does not exist already. But in a fresh application, with no users, a list of existing roles should be available in order to register.

Answers to this dilemma involve different approaches. I personally prefer creating them when seeding the database:

# db/seeds.rb

Role.create!(name: 'admin')
Role.create!(name: 'doctor')
Role.create!(name: 'nurse')

Read more…

Select2 With Simple Form in Rails

Select2 is a great JQuery plugin that customizes your select boxes to give a better user interface and experience.

Recently while working on a Rails project, I was experiencing some problems when using Select2 and Simple Form in my view.

In the view, I want to use Select2 to search for people in a Person table in the application's database. Select2 should use AJAX to hit a controller's action that performs the search. The user can then select one of the results found and it will be added to the field as a token (this is a multiple select field).

The controller action looks something like this:

def search
  @people = Person.all.where('name LIKE ? OR last_name LIKE ?',
    "%#{params[:q]}%", "%#{params[:q]}%")

  respond_to do |format|
    format.json { render json: @people.map { |p| { id: p.id, full_name: p.full_name } } }

Read more…