12

現在、ユーザー アクティビティ通知システムを処理するアクティビティ モデルがあります。アクティビティ オブザーバーは、何らかのアクションが発生すると (新しい記事の作成など)、新しいアクティビティを作成します。ここで、現在のユーザーが見たことのないこれらのアクティビティ通知の数を記録したいと思います (Facebook の通知宝石に似ています)。ユーザーが通知リンクをクリックするたびに、数値は 0 にリセットされ、通知が作成されるたびにカウントが 1 ずつ増えます。各ユーザーのこのデータはどこに保存しますか? セッションを使用すると機能しますか、それとも他の方法が優れていますか?

4

2 に答える 2

20

これには、正規化と非正規化という 2 つの方法があります。私は正規化されたものから始めます:

アプローチ 1: 正規化

ここでは、アクティビティ、通知 ("user_activities")、およびユーザーの 3 つのモデルが使用されているようです。ここでの仮定が間違っている場合は修正してください。

  • アクティビティの belongs_to :user および has_many :notifications (1 人のユーザーがアクティビティを実行し、複数のユーザーがアクティビティの通知を受け取ります)
  • 通知の belongs_to :activity および belongs_to :user であり、"read" 属性 / フラグを持っている
  • ユーザー has_many :通知

アクティビティの after_create コールバックでは、モデルはそのアクティビティの通知が必要なユーザーを判断し、それぞれの通知オブジェクトを作成して通知する必要があります。

通知では、アクティビティの読み取りフラグが false であるという条件を指定する 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

このアプローチの欠点は、通知モデルを排除したことです。そのため、ユーザーは通知の生の数しか得られず、通知とそれに関連するアクティビティの詳細なリストを表示できません。ハイブリッド アプローチを使用することもできますが、目に見えない通知数について 2 つの信頼できる情報源に対処するのは危険であることを覚えておいてください。

補足:モデルで直接 after_create を呼び出すのではなく、オブザーバーで notify_users を呼び出す方が理にかなっている場合があります。

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 に答える