Skip to content

synth/social_feed

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SocialFeed
==========

This plugin adds a social feed to your rails application. Users can decide what kinds of events they want to see on their social feed and also wether they want to be sent an email when an event occurs. They can also decide wether others will receive a notification on their social feed concerning their own actions.

How it works
============

The plugins adds the following things to your application
* a FeedEvent model - this represents an event on the social feed - you will subclass the SocialFeed to create your own custom events
* a SocialFeedsController - this controller has actions for:
  * displaying the social feed for a user (index)
  * destroying a SocialFeed
  * displaying a settings page where users can 
    * subscribe to and unsubscribe from events
    * subscirbe to and unsubscribe from receiving emails for events
    * enable/disable the creation of events concerning their own actions in the application
* a migration that adds 3 fields to your users table to store the event subscriptions


Installation
============

If you are on rails >= 2.1 (which supports git) you can simply do a 
script/plugin install git://github.com/langalex/social_feed.git

If not you need to do this from your rails root:

cd vendor/plugins
git clone git://github.com/langalex/social_feed.git --depth 1
cd social_feed
ruby install.rb
cd ../../..

for the rest see the INSTALL file

Assumptions
===========

the socialfeed plugin assumes that:

* your users are represented via the User model
* your users have an email attribute (used by the feed event mailer)
* the controllers in your application have access to the currently logged in user via the current_user method

Basic User Experience
=====================

After the plugin is installed you can direct your users to the /feed_events url which will show them their personal social feed. To customize their events the users should go to /feed_events/settings

How to create custom events types
=================================

To create a custom event you should use the built-in feed_event generator:

e.g.: script/generate feed_event new_friend

This creates a new class NewFriendEvent in the app/models/feed_events directory (the class representing the event) as well as a new_friend_hint.html.erb file in the app/views/feed_events directory (this gets rendered on people's social feed page). First thing you probably want to do is to customize the hint file.

Secondly you should also customize the two description lines in the model, which will be used on the setting page. By commenting out either line, you can remove the corresponding line from the setings page.

If you want your users to be able to receive emails for your new event, add a method new_friend(event) to the FeedEventMailer found in app/models/. You can call the convenience method create_event_message(subject, event) to send your mails. After adding the method a checkbox for this event will automatically appear on the settings page.  You will also need to add a mailer template in app/views/feed_event_mailer/deliver_new_friend.html.erb and will have access to @event for the event information.

Ex.(in feed_event_mailer.rb)
  def new_friend_event(event)
    create_event_message("Put the subject here", event)
  end 

Creating actual events
======================

In order for the social feeds of your users to get filled with events you have to create instances of your custom event classes. You have a number of choices here. I would recommend to use the rails observers, so for a NewFriendEvent you would probably create a FriendShipObserver with an after_create hook that creates the event after a new friendship has been created. As soon as you start creating lots of events for a single action (e.g. tell every user that user X and user Y are now friends) I would highly recommend using something asynchronous like the workling plugin and starling.

An event requires two attributes, a user and a source. The user is the user who sees the event on her social feed, the source is the object that sort of caused the event, which in this example would be the friendship, e.g.

NewFriendEvent.create :user => some_user_interested_in_the_event, :source => new_friendship

There is a serialized #details field on the FeedEvent model so that you can put any other auxiliary information on to the feed.  See example usage.

If you want the enable/disable event feature to work (a.k.a. privacy settings), the source must implement a user method which returns the user who caused the event. That user's privacy settings are then check before creating the actual FeedEvent instance.

Warning: Do not create events using create! but use the create method (without the bang) - when a user has not subscribed to an event, a validation in the FeedEvent class will fail so that the event won't be created. If you use the create! method you will get an exception instead.

Showing the feed
=================
You can access the feed through the feed_events controller which can be accessed by the routes: feed_events_path or feed_events_url
If you want to render the feed within another controller: 
  <%= render :partial => 'feed_events/user_feed', :object => @feed_events %>
  where @feed_events is whatever set of events(can be multiple types) that you want.  Rails will introspect on the type of event in order to ultimately determine which feed hint partial to render.

An example query to get @feed_events might be:
  current_user.feed_events.find :all, :limit => 20, :order => 'created_at DESC'

Summary Events
==============
On event classes that you would like to have summary events, or events that group other events, you can include the FeedEventSummary mixin.

Historical Feeds
================
In order to have historical feeds, eg, if you subscribe to an event that has been around a while and want to have that appear in your feed, 
there needs to be a central user who has every kind of feed, or rather all the ones you want to maintain a history for.

When subscription takes place, the last 10 or 20 items(configurable) of this type are copied 
over from the system user's feed to that user's feed.  This will also serve the dual purpose of a master log of all activity on the system.

The reason why I copy the feed items is because the alternative, as I see it, would be to maintain normalize the db and maintain a join table 
of users habtm events.  This way its very easy for a user to remove events from their feed. 


In order to do this, just create a new user in the system, subscribe them to all the events, and edit social_feed.yml to include system_feed_id

Configuration
=============

You can setup the from address used by the FeedEventMailers create_event_message method in the social_feed.yml in your config folder.
You can turn caching of the hints on/off at the environment level by setting SocialFeed::Conf.cache_hints = false
You can turn on historical feeds(see above) by setting a system_feed_id which is the id of the User instance that is subscribed to all the feeds you want to 
maintain a history for.  Also specify, historical_feed_count to limit the copying of the feed to a certain number of events.

Example Usage: Feed for updates on the User model
==============
I stash the changes on my model before the model is updated, so that the feed(created after the save) will know exactly what was changed(Here, I'm avoiding counting changes to the subscription as a change)

  attr_accessor :stashed_changed
  before_update :stash_changes
  after_update :update_feed, :unless => Proc.new{|u| u.stashed_changes.reject{|k,v| k == "feed_event_subscriptions"}.empty?}

  def stash_changes
    self.stashed_changes = self.changes
    self.stashed_changes.delete("updated_at")#we don't want to count this as an attribute that was changed
    self.stashed_changes
  end
  
  #this updates all subscribed users when any particular user updates their "profile"
  def update_feed
    User.find(:all).each do |u|
      UserUpdateEvent.create :user => u, :source => self, :details => stashed_changes
    end
  end  
  
  
Gotchas
=======

For all models of you application you use as a source for a FeedEvent, add a
:has_many :feed_events, :dependent => :destroy
so that the feed events are destroyed when objects are destroyed. Otherwise the social feeds of you users will get into trouble with sources of events missing.
I have hierarchical feed events, so I have situations like:
  class ProjectFeedEvent < FeedEvent; end
  class ProjectAddedEvent < ProjectFeedEvent; end
There is a quirk in rails, that when using STI with more than one level of inheritance and cache_classes=false, the subclasses are not reloaded properly and thus ProjectFeedEvent.find(:all) doesn't properly include the subclasses in the find after multiple(>= 2) web requests.  The workaround is to explicitly name subclasses:
  class ProjectFeedEvent < FeedEvent
    def subclasses;[ProjectAddedEvent];end
  end

Contact
=======

Copyright (c) 2008 Alexander Lang, released under the MIT license

Contact: email: alex[at]upstream-berlin.com, twitter: langalex, blog: http://upstream-berlin.com/blog, skype: langalex

About

a ruby on rails plugin to create and display a social feed

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 100.0%