开发者

Creating a news feed in Rails 3

I want to create an activity feed from recent article and comments in my rails app. They are two different types of activerecord (their table structures are different).

Ideally I would be able to create a mixed array of articles and com开发者_如何学JAVAments and then show them in reverse chronological order.

So, I can figure out how to get an array of both articles and comments and then merge them together and sort by created_at, but I'm pretty sure that won't work as soon as I start using pagination as well.

Is there any way to create a scope like thing that will create a mixed array?

One of the other problems for me, is that it could be all articles and it could be all comments or some combination in between. So I can't just say I'll take the 15 last articles and the 15 last comments.

Any ideas on how to solve this?


When I've done this before I've managed it by having a denormalised UserActivity model or similar with a belongs_to polymorphic association to an ActivitySource - which can be any of the types of content that you want to display (posts, comments, up votes, likes, whatever...).

Then when any of the entities to be displayed are created, you have an Observer that fires and creates a row in the UserActivity table with a link to the record.

Then to display the list, you just query on UserActivity ordering by created_at descending, and then navigate through the polymorphic activity_source association to get the content data. You'll then need some smarts in your view templates to render comments and posts and whatever else differently though.

E.g. something like...

user_activity.rb:

class UserActivity < ActiveRecord::Base
  belongs_to :activity_source, :polymorphic => true

  # awesomeness continues here...
end

comment.rb (post/whatever)

class Comment < ActiveRecord::Base
  # comment awesomeness here...
end

activity_source_observer.rb

class ActivitySourceObserver < ActiveRecord::Observer

  observe :comment, :post

  def after_create(activity_source)
    UserActivity.create!(
      :user => activity_source.user, 
      :activity_source_id => activity_source.id, 
      :activity_source_type => activity_source.class.to_s, 
      :created_at => activity_source.created_at, 
      :updated_at => activity_source.updated_at)
  end

  def before_destroy(activity_source)
    UserActivity.destroy_all(:activity_source_id => activity_source.id)
  end

end


Take a look at this railscast.

Then you can paginate 15 articles and in app/views/articles/index you can do something like this:

 - @articles.each do |article|
   %tr
     %td= article.body
   %tr
     %td= nested_comments article.comment.descendants.arrange(:order => :created_at, :limit => 15)

This assumes the following relations:

 #app/models/article.rb
 has_one :comment # dummy root comment

 #app/models/comment.rb
 belongs_to :article
 has_ancestry

And you add comments to an article as follows:

 root_comment = @article.build_comment
 root_comment.save
 new_comment = root_comment.children.new
 # add reply to new_comment
 new_reply = new_comment.children.new

And so forth.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜