Skip to main content

About In-App Navbar Notifications

General • Asked by Christophe Estanol

Chris, thanks for this one. Notifications work like a charm.

I was just wondering...

How do I create different JSONs for different models?

json.array! @notifications do |notification|
  json.id notification.id
  #json.recipient notification.recipient
  json.actor notification.actor.username
  json.action notification.action
  json.notifiable do #notification.notifiable
    json.type "a #{notification.notifiable.class.to_s.underscore.humanize.downcase}"
  end
  json.url forum_thread_path(notification.notifiable.forum_thread, anchor: dom_id(notification.notifiable))
end

Let say I want to send admin a notification every time somebody creates a thread, for example.

Or maybe in your case you receive a notification every time you have a new subscriber.

How do I create the url for every model?


Bunch of different ways you could do this, but in most cases, you're going to want to base this off two things

  1. the class name of the notifiable (ForumPost, User, ForumThread, etc)
  2. the action that happened (commented, subscribed, asked, etc)

Most of the time each time one of these two things change, you'll want to render a different snippet of JSON.

The two main approaches I'd suggest are as follows:

1 -Use a case statement to break down the notifiable to the class and action, then return the proper url for it. You could define this stuff in helper methods.

case notification.notifiable
when ForumThread
  case notification.action
  when "created"
    forum_thread_path(notification.notifiable)
  end
when User
  case notification.action
  when "subscribed"
    admin_user_path(notification.notifiable)
  end
end

This is pretty straightforward and really easy to customize the URLs. You can just adapt things easily, refactor this to methods with case statements if it gets too long and unwieldy, etc.

Of course, this breaks down when you need to start customizing the JSON more than just different URLs, so that's why option #2 might make more sense.

2 - Another way to do this is to render partials dynamically, but you have to make sure if you introduce a new notification type, you must make sure you create a template for it. This is what I generally do so that everything is nicely organized and easily customizable.

json.partial! "notifications/#{notification.notifiable.model_name.route_key}/#{notification.action}", notification: notification

For example, this would take a notification that's notifiable is a ForumThread and the action created and render the app/views/notifications/forum_threads/created.json.jbuilder template. In there you could define your details, like the different url, etc.

In most applications, notifications often end up needing more complex metadata for each one, so this is a case where it makes more sense to define each one's JSON individually. You can include different data structures where as in the first approach, it's much harder to.

It all really depends what you want to do, but I'd suggest starting with the first one, and refactoring into the second one as things progress if necessary.


So far it's been easy to implement the first approach.
I will look into refactoring when the MVP gets done. Thanks for the tips.


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.