Forum: Ruby on Rails Facebook-style news feed?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-24 16:47
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.
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (Guest)
on 2008-12-24 17:16
(Received via mailing list)
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! :)

On Wed, Dec 24, 2008 at 3:47 PM, Dave Amos
<rails-mailing-list@andreas-s.net
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (Guest)
on 2008-12-24 17:18
(Received via mailing list)
Opps sorry, obviously you can't add each result to an array and sort
them,
you'd have to merge the resulting arrays! ;)

On Wed, Dec 24, 2008 at 4:15 PM, Ashley Williams <
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-24 17:19
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!!
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (Guest)
on 2008-12-24 17:28
(Received via mailing list)
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.
:)

On Wed, Dec 24, 2008 at 4:19 PM, Dave Amos
<rails-mailing-list@andreas-s.net
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-24 18:16
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.
> :)
>
> On Wed, Dec 24, 2008 at 4:19 PM, Dave Amos
> <rails-mailing-list@andreas-s.net

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?
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (ashleyw)
on 2008-12-24 18:53
(Received via mailing list)
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! :)

On Wed, Dec 24, 2008 at 5:16 PM, Dave Amos
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-24 19:27
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! :)
>
> On Wed, Dec 24, 2008 at 5:16 PM, Dave Amos

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?
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (ashleyw)
on 2008-12-24 20:28
(Received via mailing list)
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 Amos
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-24 20:42
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 Amos

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! :)
9adaba273a566a8c3b204022f2b66410?d=identicon&s=25 Ashley Williams (ashleyw)
on 2008-12-24 21:42
(Received via mailing list)
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! :)

Good luck! :)

On Wed, Dec 24, 2008 at 7:42 PM, Dave Amos
5eb57ea1f36182bdd64e5601a73262e6?d=identicon&s=25 Nellboy (Guest)
on 2008-12-25 01:47
(Received via mailing list)
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" <a.j.r.willi...@googlemail.com>
5533357293ba87befa4fa55450753ccc?d=identicon&s=25 Dave Amos (daveamos)
on 2008-12-25 03:10
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" <a.j.r.willi...@googlemail.com>

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 %>
5eb57ea1f36182bdd64e5601a73262e6?d=identicon&s=25 Nellboy (Guest)
on 2008-12-28 15:46
(Received via mailing list)
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 Amos <rails-mailing-l...@andreas-s.net>
This topic is locked and can not be replied to.