In a Rails app I've used Faye (Rack adapter) for push notifications (for chat).
I want to use Faye for another use case (more push notifications) but I can't seem to figure it out.
In my app a model can be created from a background job so I want to refresh one of my views (say the index action) when the model gets created.
Like so:
app/models/post.rb
class Post
include Mongoid::Document
after_create :notify_subscribers
private
def notify_subscribers
Faye::Client.publish("/posts")
end
end
app/views/posts/index.html.erb
<%= subscribe_to(posts_url) do %>
uhh what do I do here? ajax call to refresh the whole page??
<% end %>
So is publishing the notification directly from an after_create callback a good idea
and when I get a message from the Faye server how to I go about implementing the "update"?
Do I just do an AJAX call to reload the data from the server? That seems like it would be slow.
Further I want to use something similar for updates to the model (say a user added some comments or the author changed the content) so thrashing the DB all the time doesn't seem like a good plan...
First of all, yes, publishing the notification with after_create
is fine. What you should do in your notify_subscribers
method is to publish all relevant information about the new post that you want to use in the client so that you don't have to make another unnecessary AJAX request when the notification is received.
So, for instance, if the title
and content
of the post are relevant for the user to see immediately after it gets created, you would do something like:
def notify_subscribers
client = Faye::Client.new('http://localhost:3000/faye')
client.publish("/posts/new", {
'title' => self.title,
'content' => self.content
})
end
...and then, in the view, you would probably use jQuery to use the data about the new post which you receive from the server. Rails code won't help you here. E.g. you would do this (assuming you're using jQuery and have included faye.js in your header):
<script type="text/javascript">
$(function() {
var client = new Faye.Client('http://localhost:3000/faye');
client.subscribe("/posts/new", function(data) {
/* do whatever you need with data */
});
});
</script>
Finally, if somehow the information you want to transfer is too complex to transfer as part of the notification, or you already have existing AJAX processes for updating your view, you could just publish the post's ID and trigger an AJAX call with jQuery in the subscribe
callback function. I'd recommend this only if necessary though.