Clayton Correia
Clayton Correia

Reputation: 273

Rails: Creating an "All activity feed" from multiple models

I have a page that has several "Feeds". In my controller I have something like this:

def index

 @plays = current_user.plays.includes(:game).order("created_at desc")

 @wants = current_user.wants.includes(:game).order("created_at desc")

 @ratings = current_user.ratings.includes(:game).order("created_at desc") 

end

and I use code like this in the view:

   <% @plays.each do |play| %>
          You played <%= play.game.name %></p>
   <% end %>

Now I want to make a forth feed on the page that is "all activity" which displays Plays, Wants and Ratings in one feed sorted by created date (desc).

Any help on the best way to do this would be great.

UPDATE: As requested code from each model, nice and simple right now:

class Play < ActiveRecord::Base
  attr_accessible :game_id, :user_id, :description

  belongs_to :user
  belongs_to :game

end

class Rating < ActiveRecord::Base

  attr_accessible :game_id, :id, :score, :user_id, :description

  belongs_to :user
  belongs_to :game


end

class Want < ActiveRecord::Base
  attr_accessible :game_id, :user_id, :description

  belongs_to :user
  belongs_to :game


end

Upvotes: 2

Views: 1150

Answers (2)

dpassage
dpassage

Reputation: 5453

I can think of two ways to do this, the quick-and-easy way and a refactored way.

The quick-and-easy way is to build an array of all the results from each of the three, and then sort it by date. So you could have something like:

@items = [] << @plays << @wants << @ratings
@items.sort_by { |item| item.created_at }

And then your view code could ask each item what its class is to figure out which text to use.

The refactored way would be to notice that your 3 classes are almost identical - in fact, Play and Want are identical except for the name, and Rating only adds a single column. So add a superclass for all 3. You may need to do a clever migration to merge the database tables into a single table using STI, but it might be the better long-run solution.

Upvotes: 0

Max Dunn
Max Dunn

Reputation: 1244

Since these come from separate tables, you won't be able to sort them in the database query. But since you already have each of the arrays, you can use Ruby to combine and sort:

@activities = (@plays + @wants + @ratings).sort_by {|a| a.created_at}.reverse

Upvotes: 2

Related Questions