Posted at

railsでredis-objectsを使う際にはredis-namespaceも使ったほうがいいかも

More than 5 years have passed since last update.

railsでredisを扱うのにredis-objectsとか便利ですよね。

なんですが、このredis-objectsをrailsのARで使用する際、デフォルトではredisのキーはモデル名:ID:指定したキーといった形になります。


たとえばこんなかんじで使ってるとして


config/initializers/redis.rb

Redis.current = Redis.new(:host => '127.0.0.1', :port => 6379)



app/models/user.rb

class User < ActiveRecord::Base

include Redis::Objects
value :hoge
end

user = User.find(1)

user.hoge.value = 'aaa'

redis-cliを使って直接確認。

$ redis-cli

redis 127.0.0.1:6379> GET user:1:hoge
"aaa"


これでも別にいいんですけど、ローカルで開発してて、立ち上げてるredisは1つだけで複数のプロジェクトでredis使ってるなんて時に、もしも他プロジェクトとモデル名とキー名がかぶると面倒なことになっちゃいます。

redisのdb機能を使うって手 Redis.new(:host => '127.0.0.1', :port => 6379, :db => 1) もあるんですが、数字でしか指定できないので「今までのプロジェクトで何番まで使ってるけ?」みたいなことになりかねないんじゃないかと。


redis-namespace

そうならないようにプロジェクト毎にキーが違えばなーって時にはコレ。

READMEにある通り、redisの呼び出し時にキーに指定したnamespaceを追加してくれます。

r = Redis::Namespace.new(:ns, :redis => @r)

r['foo'] = 1000

$ redis-cli

redis 127.0.0.1:6379> GET ns:foo
"1000"


これをredis-objectsにも使っちゃいましょう。


config/initializers/redis.rb

namespace = [Rails.application.class.parent_name, Rails.env].join ':'

Redis.current = Redis::Namespace.new(namespace,
:redis => Redis.new(:host => '127.0.0.1', :port => 6379))

namespaceはなんでもいいんですが、プロジェクト毎に違うほうがいいので、railsのアプリ名だったり環境名を使えばいいのではないかと。

この設定で先ほどのUser#hogeの例でいくと、

user = User.find(1)

user.hoge.value = 'bbb'

$ redis-cli

redis 127.0.0.1:6379> GET SampleApp:development:user:1:hoge
"bbb"

こんなかんじでキー名にnamespaceがついてます。


これでプロジェクト毎に違う名前がつくのでモデル名やらキー名を気にする必要がなくなりますねー。

よかったよかった。