/chalk_dust

Subscriptions connect models, events build activity feeds.

Primary LanguageRuby

ChalkDust

Subscriptions connect models, events build activity feeds.

Designed to scale.

ChalkDust can be used to build activty feeds such as followings and friendships by allowing models to subscribe to activity feeds published by other models.

Every time an activity occurs it is copied to all subscribers of the target of that activity. This creates an activity feed per subscriber. This results in more data but scales better and allows additional features such as the ability of the subscriber to delete/hide activity items.

Each publisher can create multiple feeds by means of topics. For example a user might publish activities with topics of 'family' or 'work'.

Code Climate Build Status endorse Bitdeli Badge

Installation

Add this line to your application's Gemfile:

gem 'chalk_dust'

ChalkDust has a dependency on ActiveRecord (3.0 or 4.0) and a soft dependency on Rails. If you are using Rails you can install the migrations as follows:

rails generate chalk_dust:install_migrations

Usage

Subscribing

A subscription connects two objects, e.g "Sam" follows "My first blog post"

ChalkDust.subscribe(user, :to => post)
ChalkDust.subscribers_of(post) # => [user]

Self-subscribing

Typically you will want to self-subscribe models on creation to themseleves so an activity feed is built for the model itself.

ChalkDust.self_subscribe(user)
# or
ChalkDust.subscribe(user, :to => user)

Undirected subscriptions

All subscriptions are directed. You can create a two way subscription, e.g a friendship, as follows:

ChalkDust.subscribe(bob,   :to => alice, :undirected => true)
# or
ChalkDust.subscribe(bob,   :to => alice)
ChalkDust.subscribe(alice, :to => bob)

Topics

If you want the subscription to only apply to activities with a particular topic you can do so as follows:

ChalkDust.subscribe(alice, :to => bob, :topic => 'work')
ChalkDust.subscribe(alice, :to => bob, :topic => 'family')

This is useful if you need to publish multiple activity feeds for an object.

Example uses for this would be seperate public and private activity streams for an object, or something like circles.

Publishing activity

Describes an event where X (performer) did Y (activity) to Z (target).

ChalkDust.publish_event(user, 'added', comment)

If the activity should be published to the feed of an object other than the target then it can be either be passed with the :root argument:

ChalkDust.publish_event(user, 'added', comment, :root => comment.post)

Topics

Optionally publish an event to a specific topic:

ChalkDust.publish_event(user, 'uploaded', photo, :root => user,
                                                 :topic => 'family')

Activity Feeds

ChalkDust.activity_feed_for(user, :since => 2.weeks.ago)
ChalkDust.activity_feed_for(post, :since => 2.weeks.ago)

Topics

Fetch an activity feed for a specific topic:

ChalkDust.activity_feed_for(user, :topic => 'family')

If you do not specify a topic you will only get activities which where not published with a topic. To get all activities (those with and without a topic) pass :all to :topic:

ChalkDust.activity_feed_for(user, :topic => :all)

You can still use 'all' as a regular topic, but you can not specify it as a symbol as you can with other topics.

Unsubscribing

ChalkDust.unsubscribe(user, :from => post)
ChalkDust.unsubscribe(user, :from => post, :topic => 'work')
ChalkDust.unsubscribe(user, :from => post, :topic => :all)

Compatibility

Tested with MRI 1.9.x, MRI 2.0.0, JRuby (1.9 and 2.0 mode) against both ActiveRecord 3.0 and 4.0.

See the build status for details.

Contributing

Contributions welcome, please fork and send a pull request.

Running Specs

To run the specs for all supported combinations of Ruby and ActiveRecord:

wwtd

To run the specs for a specific version of ActiveRecord:

env BUNDLE_GEMFILE=$PWD/gemfiles/activerecord-3.0 bundle exec rspec spec
env BUNDLE_GEMFILE=$PWD/gemfiles/activerecord-4.0 bundle exec rspec spec

Thanks

Thanks to Igor @ Lifetrip Limited for allowing this code to be open sourced.

License

Copyright (c) 2013 Lifetrip Limited

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.