Ask A Question

Notifications

You’re not receiving notifications from this thread.

How to use In-App Notifications as an activity feed?

Adrian DeGus asked in Rails

I worked through https://gorails.com/episodes/improving-in-app-notifications yesterday and it works great.

I tried to use this same system create activity feeds for my different models, but ran into a problem. Duplicates. Every activity/notification contained (seemingly) duplicate records, most likely due to the fact that a notification record is created for each user. So when I iterate through all notifications it lists out what appear to be duplicates.

  1. Is there any way to single out one record for each event? I tried pulling out records only for actors, but it didn't work.

As an alternative I also tried working through https://gorails.com/episodes/activity-feed-from-scratch but couldn't figure out how to create event records from within controller actions. I tried this in my comments_controller but it prevented comments from being created:

@comment = current_user.events.create(action: "commented", eventable: @task)
  1. What's the correct way to create events from within controller actions?

Option 1 would be awesome, option 2 would be great... option 3 (public_activity gem or getstream.io would suck).

Any help is appreciated :)

Reply

After spending more time on this I can see that using the notifications system for an activity feed isn't going to work very well. So moving onto implementing 'activity feeds from scratch'...

I just need to be able to create the events from within controller actions.

Here is what I tried in my comments_controller:

@task_id = params[:task_id]
@comment = Comment.new(comment_params)
@comment.update_attributes(task_id: @task_id, user_id: current_user.id)
@comment.save!

@comment = current_user.events.create(action: "commented", eventable: @task) 

(@task.users.uniq - [current_user]).each do |user|
      Notification.create(getter: user, doer: current_user, action: 'commented', notifiable: @task)
    end

But this prevents comments from being created for some reason.

What am I doing wrong?

Reply

Hey Adrian,

What do you mean that it prevents comments from being created? Are you getting an error?

One thing I noticed is you're doing update attributes before you save, so it will try to save to the database twice there. The update_attributes call will hit the database. I believe you'd actually want:

@comment = Comment.new(comment_params)
@comment.assign_attributes(task_id: @task_id, user_id: current_user.id)
@comment.save!

That could also be written a few different ways, for example simply merging iin the task_id and user_id into params and making it a one-liner instead.

One other recommendation, when you're creating the other events / notifications you might consider doing this in an ActiveRecord transaction so you can get a bulk insert into the database which should be quicker than one-by-one.

Reply

Hey Adrian and Chris,

I am about to integrate the similar feature(activity feeds) for one of the app, I thought public_activity would be a good choice. Can you please tell me why its not a good chioce. may be I can save myself from some frustration :P

Reply

Depending on the size of your user base, activity feeds can rapidly growing and become the slowest part of your app.
If your user base won't become massive, you can code it yourself, and Chris detailed a very good implementation.
A more robust alternative is https://github.com/ello/streams which is a wrapper around SoundCloud's Roshi.
A scalable and easy to implement solution is https://getstream.io/

Hope that helped you.

Reply

Thanks for the direction Chris! My activity feed is working perfectly now.

I hadn't realized that I was hitting the db twice, using assign_attributes now and am going to use transactions for notifications next.

I got comments to create properly by noticing the mistakes I had made with:

@comment = current_user.events.create(action: "commented", eventable: @task) 

It should have been:

@task.events.create(action: "commented", eventable: @task, user_id: current_user.id)

Abhinay, I personally decided against public_activity because I couldn't get it to work properly with my nested resources. Activity feeds from scratch gave me the control I needed to tweak everything to work with my particular app. Plus I had already setup notifications using Chris' screencast and the activity feed works similarly, really helped keep things streamlined.

Reply

@Thomas M,

Looks pretty good alternative but I am not very familiar with Go so it might eat some extra time. Is there a Rails way of implementing Streams(Roshi/Go) ?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 87,563+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.