I’m building a notifications system for an social networking app, here is what I got so far:
# app/controllers/v1/comments_controller.rb
class V1::CommentsController < ApplicationController
def create
post = load_post
comment = post.comments.new(protected_params)
comment.user = current_user
if comment.save
create_notification(
user_ids: post.subscriber_ids,
action: :make_comment,
target: post
)
render_created(comment)
else
render_bad_request(comment)
end
end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
def create_notification(user_ids:, action:, target:)
NotificationsWorker.perform_async(
current_user.id,
user_ids,
action,
target.class.name,
target.id
)
end
end
# app/workers/notifications_worker.rb
class NotificationsWorker
include Sidekiq::Worker
sidekiq_options queue: :notification
def perform(actor_id, user_ids, action, target_type, target_id)
actor = User.find(actor_id)
target = target_type.constantize.find(target_id)
notifications = []
ActiveRecord::Base.transaction do
user_ids.each do |user_id|
notification = Notification.create(
user_id: user_id,
action: action,
actor: actor,
target: target
)
notifications.push(PushNotification.new(notification).notification)
end
end
Urbanairship.batch_push(notifications)
end
end
# app/models/push_notification.rb
class PushNotification
def initialize(notification)
@notification = notification
end
delegate :actor, :target, to: :@notification
def notification
{
aliases: [@notification.user_id],
aps: { alert: alert_message, badge: '+1' },
meta: {
action: @notification.action,
target.class.name => target.id
}
}
end
private
def alert_message
case @notification.action
when 'follow_user'
"#{actor.short_name} started following #{target.name}"
when 'like_post'
"#{actor.short_name} likes #{target.dog.name}'s status"
when 'make_comment'
"#{actor.short_name} commented on #{target.dog.name}'s status"
end
end
end
In this particular example, whenever a user comments on someone else’s post, they will register in subscribers list and notify all existing subscribers. I feel I’m not quiet happy about this design yet. So I hope to get some feedbacks from you guys here and share similar experiences on building notifications in your apps?
Sorry to have a quiet long post like this