In a Rails app I want to combine several models into a single activity feed.
For example, I have Post, Comment, Photo, Status models. Each one belongs to a User, an Institution, and a City. On a User/Institution/City show page I want to display a chronological list of the latest activity.
From reading around and from other questions on SO, there appear to be two schools of thought on this.
- Create a polymorphic ActivityFeed model where e.g. a User
has_many :posts as: feedable. Then render the ActivityFeed collection on the respective show pages. - Create and render a combined array e.g.
@user_feed = @user_photos + @user_comment +..
But I haven’t seen much discussing the pros and cons of each approach.
Has any one else attempted something similar? What issues should I be thinking about or planning for in choosing an approach? How well do each perform (especially as the database gets larger)?
My requirements are:
- To display all items that belong to the parent model.
- To have several different types of parent model (User, Institution, City, etc).
- To render a different view partial for each item in the activity feed, depending on its class.
Grateful for any thoughts, personal experiences, or pointers to further information on this. Should I be looking for a third option? I’m particularly interested in the performance of creating a combined array from several queries.
Thanks
Let me add a few more issues to your requirements
For me 5 and 6 and 7 defo tips it in favour of the first option, my code would be:
your scope for city newsfeed (demonstrating 1,2,6)
note that this is a cheap search on one table only that can already give you enough for a quick list since association loading (would be
.includes(:activities)) is not necessary to display something like.4 is trivial if activity is a separate class and 5 also smooth with standard activity controller. for shared rendering partials like the quicklist views/activities will be a natural place.
7 is easily done with the counter_cache.
as a bonus, by allowing has_many :activities on each type, you could distinguish types of activities, like create, update, read, etc.
hope this helps