Facebook-style news feed?


#1

I’ve tried googling for more information on this, but I’ve come up
empty.

Has anyone implemented a facebook-style news feed on their rails app?
Here’s my situation. I have a recipe-sharing site, and I’d like to have
a feed that shows a user when a few different actions happen to them or
their recipes (like adding as a favorite, adding as a follower, etc.).

I don’t know how to essentially take three or four queries and combine
them into one feed that I can display in my view chronologically. Is
there a plugin for this that I don’t know about?

Thanks for the help; any tips are helpful.


#2

I’m sure it can be done in one query, but this is how I’d do it:

combined = Array.new
combined << Comment.all
combined << Favorite.all

…etc. Though you’ll want to set limits to the above

@feed = combined.sort { |x,y| y.created_at <=> x.created_at }

…and then when looping through in your views, use “object.class.to_s” to
see
what it is, and change the icon, style, etc accordingly.

I look forward to any other replies which have a better way of doing it,
'cause multiple queries isn’t great, but a news feed can be cached very
easily so I don’t see much problem with the above! :slight_smile:

On Wed, Dec 24, 2008 at 3:47 PM, Dave A.
<removed_email_address@domain.invalid


#3

Opps sorry, obviously you can’t add each result to an array and sort
them,
you’d have to merge the resulting arrays! :wink:

On Wed, Dec 24, 2008 at 4:15 PM, Ashley Williams <


#4

That makes sense – I hadn’t thought about stuffing the queries into an
array. If I get some time today I might fiddle with that and see how it
works.

Thanks!!


#5

Ashley Williams wrote:

You could also create an Actions model which has_many
favourites/comments/ect. which seems like a more sensible solution; it’d
join and include all the data from the sources tables for you in one
query.
:slight_smile:

On Wed, Dec 24, 2008 at 4:19 PM, Dave A.
<removed_email_address@domain.invalid

Clever! I’m not sure I’m clever enough to implement it correctly,
though. I created a Newsfeed model and did the has_many/belong_to stuff,
but I’m not sure how to do my controller code.

Lets say I wanted to have a feed of all actions a user takes (comments,
recipes posted, favorites, etc.). I tried:

@feed = Newsfeed.find(:all, :conditions => [“user_id = ?”, @user.id])

But I get this error: Mysql::Error: #42S02Table
‘cookingfriend_development.newsfeeds’ doesn’t exist: SELECT * FROM
newsfeeds

I think I need a database? How else do I query the model?


#6

You could also create an Actions model which has_many
favourites/comments/ect. which seems like a more sensible solution; it’d
join and include all the data from the sources tables for you in one
query.
:slight_smile:

On Wed, Dec 24, 2008 at 4:19 PM, Dave A.
<removed_email_address@domain.invalid


#7

You’d have to have some polymorphic columns in an “actions” table,
something like:

id #=> 1
comment_id #=> 15
favourite_id #=> nil
user_id #=> 10
created_at #=> Wed Dec 17 03:14:41 0000 2008

Then you can do something like:

Newsfeed.all(:conditions => { :user_id => 1 }, :include => [:comment,
:favourite], :limit => 25)

…At least I THINK that’d work, but I think it would — something
similar anyhow! :slight_smile:

On Wed, Dec 24, 2008 at 5:16 PM, Dave A.


#8

Ashley Williams wrote:

You’d have to have some polymorphic columns in an “actions” table,
something like:

id #=> 1
comment_id #=> 15
favourite_id #=> nil
user_id #=> 10
created_at #=> Wed Dec 17 03:14:41 0000 2008

Then you can do something like:

Newsfeed.all(:conditions => { :user_id => 1 }, :include => [:comment,
:favourite], :limit => 25)

�At least I THINK that’d work, but I think it would � something
similar anyhow! :slight_smile:

On Wed, Dec 24, 2008 at 5:16 PM, Dave A.

Thanks, duh, that makes sense to me. I just created the database, and
now I’m going to start writing methods that connect everything with the
actions table so I can get some data in there.

I have a performance-related question. I don’t think it’d be too
demanding to ask the action table “show me everything this user has
done” because it’s just a :conditions => [:user_id = 1}. How crazy is it
to ask the actions table “show me every time someone else favorites or
comments on my recipe”? I believe this is possible with the actions
table you have laid out, but will it take a while to grind out of the
database?


#9

Its defiantly possible, though I’m not that good with rails yet, so
I’m not sure exactly how you add conditions on other tables. But I
don’t think the performance would be that bad, it’d only have to span
a few tables, which isn’t that bad considering an average profile page
would do the same; plus it can be cached a lot too.

On Wed, Dec 24, 2008 at 6:27 PM, Dave A.


#10

Ashley Williams wrote:

Its defiantly possible, though I’m not that good with rails yet, so
I’m not sure exactly how you add conditions on other tables. But I
don’t think the performance would be that bad, it’d only have to span
a few tables, which isn’t that bad considering an average profile page
would do the same; plus it can be cached a lot too.

On Wed, Dec 24, 2008 at 6:27 PM, Dave A.

Yeah, good point. If the table got crazy huge, I could start cutting off
really old entries to minimize the calculations.

Thanks so much for the the help! I’ve already got a little feed that
shows you your recent activity, and I think it’s trivial to create feeds
for all activity your friends have taken and all activity on recipes you
created. This is exciting! :slight_smile:


#11

Personally, I’d probably take the approach of adding a ‘feed_item’
table to the database and tie it to the user with a ‘has_many’
relationship

then when user x updates their favourites, you can put something like
“#{user.name} has added #{recipe.name} to their favourites” into the
feed_item table with a user_id passed in as a parameter, and you can
make these feed items appear on the homepage of whoever is following
or is friends with this user…

no plugins required (i don’t think anyway)

On Dec 24, 8:41 pm, “Ashley Williams” removed_email_address@domain.invalid


#12

Well it would be paginated, only X at a time will be grabbed for each
page — 1-25, 26-50, 51-75, or something. Wont make much difference at
a million rows than when you had only a handful! :slight_smile:

Good luck! :slight_smile:

On Wed, Dec 24, 2008 at 7:42 PM, Dave A.


#13

Hi Dave

I don’t see the need to tie the ‘feed_entry’ to any other models
except for the user. All that’s being passed to the table are strings,
and you only want to see the messages associated with a certain user’s
network (i.e. other users)… Or maybe you want to see messages
associated with recipes.

It really just depends on what you want to do… it’s all possible
(that’s the beauty of it!!!)

cheers for the thoughts

On Dec 25, 2:10 am, Dave A. removed_email_address@domain.invalid


#14

Nellboy wrote:

Personally, I’d probably take the approach of adding a ‘feed_item’
table to the database and tie it to the user with a ‘has_many’
relationship

then when user x updates their favourites, you can put something like
“#{user.name} has added #{recipe.name} to their favourites” into the
feed_item table with a user_id passed in as a parameter, and you can
make these feed items appear on the homepage of whoever is following
or is friends with this user…

no plugins required (i don’t think anyway)

On Dec 24, 8:41�pm, “Ashley Williams” removed_email_address@domain.invalid

I don’t think your method is very different from the one Ashley and I
were talking about. I created an “actions” table and tied it to the user
table. The thing is, I also tied it to my recipes, favorites, and
comments table. That way, whenever anyone adds a recipe, makes a recipe
a favorite, or adds a comment, an entry is added to the “actions” table.
That entry includes the id of the user so I know who did it.

When I list my feed, the view code is (truncated example):

<% @friendfeed.each do |friendfeed| %>
<%= link_to friendfeed.user.login, :controller => “users”, :action =>
“show”, :id => friendfeed.user.id %> favorited <%= link_to
friendfeed.recipe.title, :controller => “recipes”, :action => “show”,
:id => friendfeed.recipe.id %>
<% end %>