merit-gem

Notifications - flash message, how to


Looking for a way to notify the user, via a flash message, that they've obtained a new badge.

I have my observer setup per the instructions here: https://github.com/merit-gem/merit#getting-notifications

My observer code is:

class ReputationChangeObserver

  def update(changed_data)  
    description = changed_data[:description]
    flash[:info] = description
  end

end

Rails complains about the following:

undefined local variable or method `flash' for #<ReputationChangeObserver:0x0000000586d648>

I understand that flash is a part of the base actioncontroller. However, I don't know how the observer could access flash or session since it seems to exist outside of the rails framework.

What am I missing? There don't seem to be any examples or tutorials on how to implement user notifications (that I could find).

Would someone please lend their wisdom?


Solution

  • As far as I know you can't access flash from the observers. You need a separate way of delivering the message to the user on a web page. For example, within the update() method, capture the information you want to show and create a record of the activity that will be consumed by your controller. You can set up your own model or use one of the gems that deal with activity feeds.

    There could be a few different ways to do the notification depending on your use case:

    1. Realtime notification using something like: http://railscasts.com/episodes/401-actioncontroller-live?view=asciicast (You could just publish the data right in the update() above and let the subscriber consume it)
    2. Long polling on webpage to pull any updates: http://railscasts.com/episodes/229-polling-for-changes-revised?view=asciicast
    3. Show updates on user's page load: Set up before_action filter and check if user has a new activity feed. If yes, add it to flash.

    1,2 will be suitable if you know you user will stay on one page for a while. For example, if your app has a dashboard page or timeline page (like FB or Twitter). 3 is ideal if you know your user will load(visit) many different pages, but your user won't be able to get the update until the page is reloaded.

    In short, there's no way to directly push your notification to flash in observers. The updates happens in the background and it has no knowledge of the controller. You need to store(or publish in case of live updates) updates and, when user loads your app, have your controller pull the updates to create notification to the user.

    Hope this helps.