Notification System in Rails

How to implement a simple notification system in Rails?

This is possible since Rails 5 and Action Cable. A good tutorial can be found here:

https://blog.heroku.com/real_time_rails_implementing_websockets_in_rails_5_with_action_cable

It involves creating a 'channel' which each user subscribes to, however it's far easier to run through a tutorial like the one above rather than have me explain step by step. The above is for creating a chat room, so you'd just swap the new message for a new notification.

notification system in application

You need to store a reference to the recipient in the notification.

t.integer :recipient_id

class Notification < ActiveRecord::Base
belongs_to :recipient, class_name: 'User'
end

Also don't set the user_id in the form, set it in the controller.
( Otherwise anybody could create a notification for anybody else, just by sending wrong input ).

class NotificationsController < ApplicationController
def create
@user = User.find(session[:user_id])
@notification = @user.notifications.new notification_params
# ...
end
end

Not a complete solution, but will point you to the right direction.

How to create notification system in rails?

I think you are on the right path.

A slightly better notifications#index

def index
@notifications = current_user.notications
@notifications.update_all checked: true
end

  1. Notify this users

    User.uniq.joins(:comments).where(comments: {id: @comment.post.comment_ids}).reject {|user| user == current_user }

Unique users that participated in the @comment's post comments, reject (remove from result) current_user.


  1. An observer as pointed out by João Daniel, it is preferred over an after_create. This "Rails best practice" describes it pretty well: http://rails-bestpractices.com/posts/2010/07/24/use-observer

Approach to a Notifications system with Rails 4

If you are open to using a gem, I would use the Public Activity gem for this. The architecture for Public Activity creates an activity record based on a recipient, an owner and a key, i.e owner: "User 1" key: commented on recipient: "User 2" post. The benefit to this is that there is only one record in the database for the activity and you can present it any way you like through different views for each type of activity.

Public Activity allows you to render different partials based on the activity key and access any of the data of the action referenced in the database. You can even create different views for a newsfeed(activities that involve the users followed by the current user) and a notification feed (activities that directly involve the current user).
This allows your notification feed to remain flexible.

Further, if you combine it with the Unread gem and some javascript you can even mark read and unread notifications (for each particular user) just like Facebook. The only drawback is that the activities would appear only on refresh or visiting the page rather than constant polling like facebook does. There is an excellent tutorial on Public Activity here.

Notification System in Rails

There is a gem called Mailboxer which has similar functionalities.

Add notification to RoR messaging inbox system

I would recommend you to go through this tutorial to build nice notification system
https://www.devwalks.com/lets-build-instagram-part-6-notifications/

Basically, you have to create new model, set dependencies with your Message model and integrate to the controller

For the email notifications, it's even simpler.
Just create new mailer and fire it on create action in messages_controller

def create
@message = @conversation.messages.new(message_params)
if @message.save
SendMessageMailer.new_message(@message).deliver_later
redirect_to conversation_messages_path(@conversation)
end
end

EDIT:
To create mailer, you should do something like this:

rails g mailer SendMessage

Go to /app/mailers/send_message_mailer.rb and add action, same type of building as controllers

def new_message(message)
@message = message
mail(to: @message.user.email, subject: 'Hey! Here is what you missed')
end

Also, create an view (email template) and code with erb code

app/views/send_message_mailer/new_message.html.erb

Im not going deep into this, I guess you can figure out how to pass interval (let's say don't send if user is online or have read the message) and differentiate with receiver/sender users

Mailer, once again, is just same type of controller. You can pass as many params as you need and use model nesting inside mailer controller and views

mailer

def new_message(message, sender, receiver)
end

controller

SendMessageMailer.new_message(@message, @message.user, params[:receiver]).deliver_later


Related Topics



Leave a reply



Submit