Help us understand the problem. What is going on with this article?

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がついてます。


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

よかったよかった。

ichi_s
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away