views:

35

answers:

2

I'm working on an application that has a few different models (tickets, posts, reports, etc..). The data is different in each model and I want to create a "feed" from all those models that displays the 10 most recent entries across the board (a mix of all the data).

What is the best way to go about this? Should I create a new Feed model and write to that table when a user is assigned a ticket or a new report is posted? We've also been looking at STI to build a table of model references or just creating a class method that aggregates the data. Not sure which method is the most efficient...

A: 

Create an Item model that includes the attributes "table_name" and "item_id". Then create a partial for each data type. After you save, let's say, a ticket, create an Item instance:

i = Item.create(:table_name => 'tickets', :item_id => @ticket.id)

In your items_controller:

def index
   @items = Item.find(:all, :order => 'created_on DESC')
end

In views/items/index.erb:

<% @items.each do |item| %>
  <%= render :partial => item.table_name, :locals => {:item => item} %><br />
<% end %>
This seems to be a more manual way of just doing STI, is there an advantage to storing the table_name, instead of type and just letting rails handle the STI?
jsiarto
+1  A: 

You can do it one of two ways depending on efficiency requirements.

The less efficient method is to retrieve 10 * N items and sort and reduce as required:

# Fetch 10 most recent items from each type of object, sort by
# created_at, then pick top 10 of those.
@items = [ Ticket, Post, Report ].inject([ ]) do |a, with_class|
  a + with_class.find(:all, :limit => 10, :order => 'created_at DESC')
end.sort_by(&:created_at).reverse[0, 10]

Another method is to create an index table that's got a polymorphic association with the various records. If you're only concerned with showing 10 at a time you can aggressively prune this using some kind of rake task to limit it to 10 per user, or whatever scope is required.

tadman
This works well and seems to be moving fairly fast. I was trying to avoid creating another model. Thanks.
jsiarto