Cleaning up duplicate controller code

The Dillema:

I am in a situation where I need to show a User's activity across multiple views and controllers. The code is starting to smell a little bit, so I'd really appreciate some guidance in cleaning it up.

I have a User controller has a "show" (/user_id/) view that renders recent activity in the sidebar, as well as a "activity" (user_id/activity) view that renders all of the user's activity. I also have a "Pages" controller that has a "dashboard" view that renders a user's activity as well.

The Code:

users_controller.rb looks like:

@activities = []
@activities += @user.skills.map { |skill| Activity.new("skill", skill, skill.created_at) }
@activities += @user.unions.map { |union| Activity.new("union", union, union.created_at) }
@activities += @user.companies.map { |company| Activity.new("company", company, company.created_at) }
@activities += @user.clients.map { |client| Activity.new("client", client, client.created_at) }
@activities += @user.schools.map { |school| Activity.new("school", school, school.created_at) }
@activities += @following_list.map { |following| Activity.new("following", following, following.created_at) }
@activities += @recommended.map { |recommend| Activity.new("recommend", recommend, recommend.created_at) }
@activities += @user.statuses.all(:limit => 5, :order => "created_at DESC").map { |status| Activity.new("status", status, status.created_at) }

sorted_activities = @activities.sort_by(&:date).reverse
@activities = sorted_activities[0..(4)]

pages_controller.rb looks like:

@your_activity = []
@your_activity += current_user.skills.map { |skill| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","skill", skill, skill.created_at) }
@your_activity += current_user.unions.map { |union| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","union", union, union.created_at) }
@your_activity += current_user.companies.map { |company| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","company", company, company.created_at) }
@your_activity += current_user.clients.map { |client| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","client", client, client.created_at) }
@your_activity += current_user.schools.map { |school| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","school", school, school.created_at) }
@your_activity += current_user.statuses.map { |status| ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}","status", status, status.created_at) }

sorted_activities = @your_activity.sort_by(&:date).reverse
@your_activity = sorted_activities[0..(35)]

Answers


There's a few ways you can do it really. You could offload it to the model, you could create a module in the lib directory and use that to build the activity arrays. One major thing too is to be sure to use a helper for displaying it on the page, and load that either into the views or a partial, depending on your needs.

You could also reduce the duplication a bit with some metaprogramming. You may need to adjust depending on your requirements. You'll need to set it up for the first set of code as well

["skill", "union", "company", "client", "school", "status"].each do |type|
  plural = ActiveSupport::Inflector.pluralize(type)
  @your_activity += current_user.send(plural.to_sym).map do |object|
    ActivityDashboard.new("#{current_user.first_name} #{current_user.last_name}","#{current_user.id}","#{current_user.avatar}",type, object, object.created_at)
  end
end

Gist of my working example: https://gist.github.com/3669117


Need Your Help

MongoDart find with problems

mongodb dart dart-async

I am implementing a MVC framework in Dart. I am implementing the find method and I want it to return the documents from that query.

Recursively call a function in Java which creates new objects

java recursion

If in a function which is getting called recursively with smaller arguments and within this function we are creating an object of a class. The objects created recursively will have the same name, h...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.