ActiveModel::Pusher
makes using Pusher in your app much easier.
The gem allows you not to care about naming channels, events and serializing records. ActiveModel::Pusher
will do it for you!
Note: to use this gem you need Pusher already working in your app.
@post = Post.create
PostPusher.new(@post).push!
This will push the following json to Pusher:
channel: 'posts',
event: 'created',
data: { id: 1 }
The original Pusher gem needs 4 things to be triggered: channel
, event
, data
and optional params
. They will be discussed below.
A channel
value for a Post
model will be one of the following:
posts
when a record has just been createdposts-1
for any other event:updated
,destroyed
, etc
Sometimes you might want to have a general channel name - like dashboard
- to which you will be pushing several models.
There are two ways to do that.
- Define a
channel
method in your model:
class Post
def channel
"dashboard"
end
end
- Define a
channel
method in your pusher:
class PostPusher < ActiveModel::Pusher
def channel(event)
"dashboard"
end
end
A newly generated pusher will look like this:
# app/pushers/post_pusher.rb
class PostPusher < ActiveModel::Pusher
events :created, :updated, :destroyed
end
The events
method is a whitelist of events. If you try to push a non-whitelisted event, an exception will be raised:
def publish
@post = Post.find(1).publish!
PostPusher.new(@post).push! :published
end
will result in InvalidEventError: 'Event :published is not allowed'
.
The three default events can be guessed by the gem automatically, you don't actually have to specify them:
def create
@post = Post.create
PostPusher.new(@post).push!
end
The gem will recognize that the record was just created and will set the event to :created
If you have custom actions in your controller - like publish
- then you should specify the event manually:
def publish
@post = Post.find(1).publish!
PostPusher.new(@post).push! :published
end
This will produce the following (given you whitelisted the published
event in your pusher):
channel: 'posts-1',
event: 'published',
data: { id: 1 }
Customizing event names may be useful when you are using a general purpose channel.
Using the example from the Customizing channels
section:
class PostPusher < ActiveModel::Pusher
def channel(event)
"dashboard"
end
end
class CommentPusher < ActiveModel::Pusher
def channel(event)
"dashboard"
end
end
We then push two different models into the general dashboard
channel:
@post = Post.create
@comment = Comment.create
PostPusher.new(@post).push!
CommentPusher.new(@comment).push!
They both will be pushed with the same event created
. Depending on your client-side architecture it might be fine, but sometimes you might want to have namespaced events: post-created
, comment-created
, etc.
You can achieve this by overriding the event(event)
method in your pusher:
class PostPusher < ActiveModel::Pusher
def event(event)
"post-#{event.underscore.dasherize}"
end
end
The data
method simply serializes your record.
By default, it will try to serialize the record with the active_model_serializers
gem.
If active_model_serializers
is not used in your application, it will fallback to the as_json
method on your record.
But seriously, just use active_model_serializers
.
You can specify additional params when calling the push!
method:
def create
@post = Post.create
PostPusher.new(@post).push! { socket_id: params[:socket_id] }
end
If you need to specify an event as well, it should go first:
def publish
@post = Post.publish!
PostPusher.new(@post).push! :published, { socket_id: params[:socket_id] }
end
A more fancier way of doing the same:
def publish
@post = Post.publish!
PostPusher.new(@post).push! :published, params.slice(:socket_id)
end
rails generate pusher Post created published
Will result in:
# app/pushers/post_pusher.rb
class PostPusher < ActiveModel::Pusher
events :created, :published
end
This is sort of an alpha version, so things may break. If you have any ideas on improving the gem, you are very welcome to contribute.
Add this line to your application's Gemfile:
gem 'active_model_pusher'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_model_pusher
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request