views:

603

answers:

1

What is the best way to implement a StackOverflow-style Recent Activities page?

I have a Gallery with user's photos and I want them to be notified when other users comment or vote their photos.

Should I create a new table which contains recent activities (updated whenever a user posts a comment or votes) or should I simply use a MySQL query?

+4  A: 

The short answer is : it depends. If you only need most recent activities and don't need to keep track of activities, or a full 'activity feed' feature, SQL is the way to go. but if you see the need to do a full activity feed kind thing, You can create a model for it.

We did a activity stream recently on our project. Here is how we modeled it

Class Activity
   belongs_to :user_activities # all the people that cares about the activity
   belongs_to :actor, class_name='user' # the actor that cause the activity

   belongs_to :target, :polymorphic => true # the activity target(e.g. if you vote an answer, the target can be the answer )
   belongs_to :subtarget, :polymorphic => true # the  we added this later since we feel the need for a secondary target, e.g if you rate an answer, target is your answer, secondary target is your rating. 

   def self.add(actor, activity_type, target, subtarget = nil)
     activity = Activity.new(:actor => actor, :activity_type => activity_type, :target => target, :subtarget => subtarget)
     activity.save!
     activity
   end 
end

in the answer_controller we do

Class AnswersController
    def create
        ...
        Activity.add(current_user, ActivityType::QUESTION_ANSWERED, @answer)
        ...
    end
end

To get a recent activity list from a user we do

@activities = @user.activities
ez
Agreed. I would start with SQL queries at first and if that gets too complex, has poor performance, or doesn't seem to fit your needs then make an Activity model.
ryanb
To avoid tainting models with this sort of Activity logging, I recommend Rails Observers:http://api.rubyonrails.org/classes/ActiveRecord/Observer.html
Bloudermilk