AlexanderZaytsev/active_model_pusher

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Active Model Pusher [![Build Status](https://travis-ci.org/AlexanderZaytsev/active_model_pusher.png?branch=master)](https://travis-ci.org/AlexanderZaytsev/active_model_pusher) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/AlexanderZaytsev/active_model_pusher)

`ActiveModel::Pusher` makes using [Pusher](https://github.com/pusher/pusher-gem) 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.

## Basic Usage
```ruby
@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.

## Channels
A `channel` value for a `Post` model will be one of the following:

1. `posts` when a record has just been created
2. `posts-1` for any other event: `updated`, `destroyed`, etc

### Customizing channels
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:

```ruby
class Post
  def channel
    "dashboard"
  end
end
```

* Define a `channel` method in your pusher:

```ruby
class PostPusher < ActiveModel::Pusher
  def channel(event)
    "dashboard"
  end
end
```

## Events
A newly generated pusher will look like this:

```ruby
# 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:
```ruby
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:

```ruby
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:
```ruby
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 events

Customizing event names may be useful when you are using a general purpose channel.

Using the example from the `Customizing channels` section:

```ruby
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:
```ruby
@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:

```ruby
class PostPusher < ActiveModel::Pusher
  def event(event)
    "post-#{event.underscore.dasherize}"
  end
end
```

## Data
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`.

## Params
You can specify additional params when calling the `push!` method:

```ruby
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:
```ruby
def publish
  @post = Post.publish!
  PostPusher.new(@post).push! :published, { socket_id: params[:socket_id] }
end
```
A more fancier way of doing the same:
```ruby
def publish
  @post = Post.publish!
  PostPusher.new(@post).push! :published, params.slice(:socket_id)
end
```

## Creating a new pusher
```
rails generate pusher Post created published
```

Will result in:

```ruby
# app/pushers/post_pusher.rb
class PostPusher < ActiveModel::Pusher
  events :created, :published
end
```

## Notice
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.

## Installation

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

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request