Edited at

redis-objectsを用いたお知らせ機能の実装

More than 5 years have passed since last update.

facebookの上に出てくるようなお知らせ機能を作成するために、

redisを用いて実装をしてみたのでメモ。

お知らせ機能の作成方法、redis-objectsの使い方の参考になれば。

プッシュ機能の実装ではないのでご注意を。

詳しいAPIの利用方法はGithubで。


環境


  • Ruby 2.0.0

  • Ruby on Rails 4.0.2

  • Redis 2.8.9

  • redis(gem) 3.0.7

  • redis-objects 0.9.1


要求

まず前提として要求の確認をしておきます。


  • 未読お知らせ件数は日をまたいだ全てのものをカウント

  • お知らせの内容、未読既読は日毎に管理


redis-objectsのインストール

以下の行を追加してbundle install

gem 'redis-objects'


redis-objectsの使い方

redis-objectsには


  1. モデルにインクルードする方法

  2. モデルと独立して利用する方法

の2通りがあります(Githubより)。

1のモデルにインクルードする方法では

モデル名:id:フィールド名

の形式でRedisのキーが作成されます。

2では独自の形式のキーが作成可能です。


実装

未読お知らせ件数と、未読既読管理についてそれぞれ実装方法をまとめます。


未読お知らせ件数のカウント

1のモデルにインクルードする方法を用います。


app/models/user.rb


class User < ActiveRecord::Base

include Redis::Objects

counter :notice_counter

end


Redis::ObjectsをインクルードするとDSLが追加されます。

counterで定義したキーはRedisのString型を用いて、整数値のデータが保存されます。

上記の例ではuser

notice_counterというString型のキーが作成されます。


notice_counter.rb


@user = User.find(1)
@user.notice_counter.incr # お知らせに追加があったとき
@user.notice_counter.decr # お知らせがpopされたとき
@user.notice_counter.reset # すべてのお知らせを消去したとき



日毎の未読既読管理

2の独立した方法を利用します。

キーを独自に定義できるので

user:id:notice:date(yymmdd)

形式で作成します。

データ型にはリストを用います。

このキーに追加する値はモデル名:idの形式で保存します。

例) comment:10


app/models/user.rb


class User < ActiveRecord::Base

def push_notice(object, date)
l = Redis::List.new(notice_key(date))
l << "#{object.class.to_s.underscore}:#{object.id}"
notice_counter.incr
end

def pop_notice(date)
l = Redis::List.new(notice_key(date))
res = l.pop
notice_counter.decr unless res
res
end

private
def notice_key(date)
"user:#{self.id}:notice:#{date.strftime('%y%m%d')}"
end
end


(例外処理などは省きました)

これで日毎の通知の未読既読の管理が可能になりました。


まとめ

以下のことについてまとめました。


  • redis-objectsのインストール方法

  • redis-objectsの使い方2通り

  • お知らせ機能の実装

RedisはAPIがわかりやすくて使っていて気持ちいいですね。

KVS一般に言えることですが、キーの設計をちゃんと行わないと収集がつかなくなってしまうのでredis-objectsのように予め使い方をしぼってくれるのは嬉しいですね。