12

我目前有一个处理用户活动通知系统的活动模型。当某个动作发生时(例如正在创建新文章),活动观察者会创建一个新活动。现在我想记录当前用户有多少活动通知没有看到(类似于 facebook 上的通知宝石)。每次用户单击他们的通知链接时,该数字应重置为 0,并且创建的每个通知都应将计数增加 1。我将在哪里为每个用户存储此数据?使用会话工作还是其他更好的方法?

4

2 回答 2

20

有几种可能的方法:规范化和非规范化。我将从标准化开始:

方法一:归一化

听起来您在这里使用了三个模型:活动、通知(“user_activities”)和用户。如果我在这里的假设有误,请纠正我:

  • Activity belongs_to :user 和 has_many :notifications (一个用户执行一个活动,多个用户收到该活动的通知)
  • 通知belongs_to :activity 和belongs_to :user 并具有“读取”属性/标志
  • 用户 has_many :通知

在活动的 after_create 回调中,模型应该确定哪些用户需要该活动的通知,然后通过为每个用户创建通知对象来通知他们。

在通知上,您可以创建一个名为 unread 的类方法,它指定活动的读取标志为假的条件:

def self.unread
  where(:read => false)
end

然后,要访问用户的未读通知计数,只需调用:

user.notifications.unread.count

当用户查看他的通知时,调用:

user.notifications.unread.update_all(:read => true)

方法 2:非规范化

在这种方法中,每当创建活动时,它应该为每个通知用户手动增加一个计数器。您可以通过以下任一方式完成此操作:

  • 用户的“unseen_count”属性
  • 非关系型数据库(如redis)中的键值对

在活动中:

def users_to_notify
  # Find a list of users to notify
end

def notify_users(users)
  users.each &:notify
end

def after_create
  notify_users(users_to_notify)
end

在用户中:

def notify
  update_attributes(:unseen_count => unseen_count + 1)
end

def see_activities
  update_attributes(:unseen_count => 0)
end

这种方法的缺点是您已经消除了通知模型,因此用户只有原始的通知计数,并且无法查看通知及其相关活动的详细列表。您可以使用混合方法,但请记住,处理两个真相来源以获得未见通知计数是有风险的。

附带说明:在观察者中调用 notify_users而不是直接在模型上调用 after_create可能更有意义:

class ActivityObserver < ActiveRecord::Observer
  def after_create(activity)
    activity.users_to_notify.each &:notify
  end
end

如果您使用观察者,您可以删除 Activity#notify_users 和 Activity#after_create。

于 2012-10-14T07:54:42.093 回答
6

请看看这个宝石:
https ://github.com/ledermann/unread

它由我编写,并以更高效的方式处理任何 ActiveRecord 对象的已读/未读状态。

于 2013-02-26T08:30:11.347 回答