Implementing Notifications in Rails

给你一囗甜甜゛ 提交于 2019-12-03 00:56:38

问题


In my application, I want to notify a user, when he/she is mentioned in a comment or a post.
The user handle is @user_name, similar to Facebook.
The database table for mentions looks like:

Mention
  mentioned_by: user_id (foreign key)
  user_mentioned: user_id (foreign key)
  comment_id: (foreign key)
  post_id: (foreign key)

I can't figure out a way to implement it though. How do Facebook / Twitter do it?

What I decided to go with, was use ActiveRecord callbacks/ Observer design pattern and whenever a new comment/post is saved to database, I can go through the contents of the post/comment, and look out for any mentions and then execute the notifications as required.

I get the feeling that there are some missing pieces and I am not getting it right.
Is this the best way of doing it?


回答1:


Facebook and Twitter are not mid-size Rails applications. They are companies. The tech that runs them is distributed and mostly custom, especially in the case of Facebook.

The part that you seem to be grasping for is how they determine who to notify in a performant and scalable way. This is where shit gets real. You can find a lot of information about the architecture behind each on of them, and there is certainly a lot of great stuff to help you think about these things, but ultimately none of it is going to be something you implement into whatever application you're building.

http://www.quora.com/What-is-Facebooks-architecture

Facebook Architecture

http://www.infoq.com/news/2009/06/Twitter-Architecture

http://engineering.twitter.com/2010/10/twitters-new-search-architecture.html

Plenty more juicy details over at Quora.


Unfortunately, none of this gets you closer to your goal. I think the most realistic thing for you to do to start out with woud be to simply tie in a service like Pusher to send messages to clients without worrying about it, use an ActiveRecord Observer to add notifications to a background queue where the workers actually send those notifications to Pusher. This is a day or less of work and it should scale well to at least 10k notifications a day. Once you start having performance problems, ditch the Observer and Pusher for something like Goliath that can handle both of the jobs locally.

Bottom line, learn what you can about large and experienced systems that have been put through the paces, but mainly just to see what problems they ran into and how they solved them. These methods aren't the same among the big guys even, and they are going to vary for each implementation.

Hopefully that helps point you in a good direction. :)




回答2:


You can use ActiveRecord callbacks while record is saved (like before_save, after_save or before_create, after_create) to go through comment content, find and create all mentions models and save them to db.




回答3:


I actually am interested in a concrete answer to this myself. I don't know how Facebook and Twitter do it, but I do know from general searches that the gem acts-as-taggable-on could get the job done. Check out https://github.com/mbleigh/acts-as-taggable-on.

Also, this question on stackoverflow might also provide you with some info: Implementing twitter-like hashtag on rails

Good luck. I encourage you to try to get more attention to this question and get a more solid answer than what I've said. :]




回答4:


Tumblr uses a Redis queuing system (like Resque) I believe to handle the volume.

Do a callback (as you mentioned) and hand it off to Resque. (There was a Railscasts about Resuqe recently)




回答5:


There is no single recommended approach for this. At an uber level, you may want to look at 'Comet programming', Polling and WebSockets [HTML5] and then choose the right combination. There are a couple of great implementations to manage push notifications in rails. Orbited, Juggernaut, PusherApp, Faye etc. You'll have to dig deep to figure out which of 'em use web-sockets & and fall-back to flash option to handle full support.

Faye gives a Node.js configuration also, but I am not sure about others.

Tentatively the steps would look something like:

  1. Save the content - queue it to parser
  2. Parse the content to find out involved users - Use Nokogiri or equivalent.
  3. Comet/Poll it to involved users in current_session as a separate process if you're looking at Twitter like approach.
  4. //Do other things with Post record
  5. Push notifications to involved users and destroy() when they come online later.

    Hope that gives some direction.




回答6:


I know this question is outdated but I released a MentionSystem gem recently to rubygems.org that allows to create mentions between mentionee objects and mentioners, it also allows you to detect mentions in facebook / twitter styler like @username1 and #hashtag in order to create the mentions.

The gem is hosted at github: https://github.com/pmviva/mention_system

Lets say you have a Post that can mention users in the form of @username.

you have the class

class Post < ActiveRecord::Base
  act_as_mentioner
end

and

class User < ActiveRecord::Base
  act_as_mentionee
end

Then you define a custom mention processor:

class PostMentionProcessor < MentionSystem::MentionProcessor
  def extract_mentioner_content(post)
    return post.content
  end

  def find_mentionees_by_handles(*handles)
    User.where(username: handles)
  end
end

Then in your Posts controller create action you have:

def create
  @post = Post.new(params[:post])
  if @post.save
    m = PostMentionProcessor.new
    m.add_after_callback Proc.new { |post, user| UserMailer.notify_mention(post, user) }
    m.process_mentions(post)
  end

  respond_with @post
end

If your post has @user1, @user2 and @user3 in its content the mention processor will parse user1, user2, user3, will find users with username [user1, user2, user3] and then create the mentions in the database, after each of the mentions it will run the after callback that in the example will send an email notifying the mention between post and user.



来源:https://stackoverflow.com/questions/6772203/implementing-notifications-in-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!