#407 Activity Feed from Scratch pro
Feb 14, 2013 | 14 minutes | Views
Creating an activity feed presents some interesting challenges. Here I share my thought process behind my implementation including when to use callbacks and a few tricks with partials.
- Download:
- source codeProject Files in Zip (93.7 KB)
- mp4Full Size H.264 Video (29.3 MB)
- m4vSmaller H.264 Video (15.5 MB)
- webmFull Size VP8 Video (20 MB)
- ogvFull Size Theora Video (34.3 MB)
Resources
terminal
rails g resource activity user:belongs_to action trackable:belongs_to trackable_type rake db:migrate
application_controller.rb
def track_activity(trackable, action = params[:action]) current_user.activities.create! action: action, trackable: trackable end
recipes_controller.rb
track_activity @recipe
comments_controller.rb
track_activity @comment
activites_controller.rb
def index @activities = Activity.order("created_at desc") end
presenters/activity_presenter.rb
class ActivityPresenter < SimpleDelegator attr_reader :activity def initialize(activity, view) super(view) @activity = activity end def render_activity div_for activity do link_to(activity.user.name, activity.user) + " " + render_partial end end def render_partial locals = {activity: activity, presenter: self} locals[activity.trackable_type.underscore.to_sym] = activity.trackable render partial_path, locals end def partial_path partial_paths.detect do |path| lookup_context.template_exists? path, nil, true end || raise("No partial found for activity in #{partial_paths}") end def partial_paths [ "activities/#{activity.trackable_type.underscore}/#{activity.action}", "activities/#{activity.trackable_type.underscore}", "activities/activity" ] end end
activities/index.html.erb
<% @activities.each do |activity| %> <%= ActivityPresenter.new(activity, self).render_activity %> <% end %>
activities/_recipe.html.erb
<%= activity.action.sub(/e?$/, "ed") %> recipe <%= link_to recipe.name, recipe if recipe %>
activities/comment/_create.html.erb
<% if comment %> commented on <%= link_to comment.recipe.name, comment.recipe %> <% else %> added a comment which has since been removed <% end %>