edy hub

プログラミングやライフスタイルについて書き綴っています

Redis ObjectsをRailsで使ってみる

はじめに

これはRedis導入後に、Redis Objectsの使い方を学ぼうと思った一人の若者の備忘録です。

GitHubリポジトリを参考にしています。

GitHub - nateware/redis-objects: Map Redis types directly to Ruby objects

Gemの導入

はじめに、Gemfileにgemを追加します。

gem 'redis-objects'

モデルクラスに組み込んでみる

Redis::Objectsをモデルクラスにインクルードします。 Redis::Obejcetsは ユニークな値を返すメソッドであるid を備えているクラスであれば効果的に活用できます。 そして、自動的に各オブジェクトに対してユニークなキーを発行してくれたりします。

例:下記のようなフォーマット

model_name:id:field_name

Userクラスで試してみる

class User
  include Redis::Objects
  counter :my_posts
  def id
    1
  end
end

user = User.new
user.id  # 1

user.my_posts.increment
user.my_posts.increment
user.my_posts.increment
puts user.my_posts.value # 3

user.my_posts.reset
puts user.my_posts.value # 0

user.my_posts.reset 5
puts user.my_posts.value # 5

スタンドアロンな用法

Counters

任意のcounter_nameをキーとしてRedisに保存される仕組み。

@counter = Redis::Counter.new('counter_name')
@counter.increment  # or incr
@counter.decrement  # or decr
@counter.increment(3)
puts @counter.value

Values

シンプルな値も簡単に取り扱えます。

@value = Redis::Value.new('value_name')
@value.value = 'a'
@value.delete

Lists

ListsRubyの配列のような働きをします。 配列を扱う際に登場するメソッドが同じように使えて便利。

@list = Redis::List.new('list_name')
@list << 'a'
@list << 'b'
@list.include? 'c'   # false
@list.values  # ['a','b']
@list << 'c'
@list.delete('c')
@list[0]
@list[0,1]
@list[0..1]
@list.shift
@list.pop
@list.clear
# etc

配列の最大保持数も指定できます。 ※ :maxlengthオプションを使います。最も古い要素を配列外に出します。

# 最大10個の要素だけ保持したいとき。
@list = Redis::List.new('list_name', :maxlength => 10)

Hashes

HashesもRubyのHashのような働きをします。Redis独自の仕様もあります。 RubyのHashとの衝突を避けるために、HashKeyという命名になっています。

@hash = Redis::HashKey.new('hash_name')
@hash['a'] = 1
@hash['b'] = 2
@hash.each do |k,v|
  puts "#{k} = #{v}"
end
@hash['c'] = 3
puts @hash.all  # {"a"=>"1","b"=>"2","c"=>"3"}
@hash.clear

Redis上では、数字は文字列になることに注意してください。

Sets

SetsはRubyのSetクラスのようなものです。 順序立てられたものではないですが、要素の一意性が担保されます。

@set = Redis::Set.new('set_name')
@set << 'a'
@set << 'b'
@set << 'a'  # dup ignored
@set.member? 'c'      # false
@set.members          # ['a','b']
@set.members.reverse  # ['b','a']
@set.each do |member|
  puts member
end
@set.clear
# etc

Sorted Sets

プロパティーの一意性に伴い、Sorted Setsはハッシュと配列の両取りをしたような働きをします。 ハッシュのように割り当てることができ、取り出すときは配列風になります。

@sorted_set = Redis::SortedSet.new('number_of_posts')
@sorted_set['Nate']  = 15
@sorted_set['Peter'] = 75
@sorted_set['Jeff']  = 24

# Array access to get sorted order
@sorted_set[0..2]           # => ["Nate", "Jeff", "Peter"]
@sorted_set[0,2]            # => ["Nate", "Jeff"]

@sorted_set['Peter']        # => 75
@sorted_set['Jeff']         # => 24
@sorted_set.score('Jeff')   # same thing (24)

@sorted_set.rank('Peter')   # => 2
@sorted_set.rank('Jeff')    # => 1

@sorted_set.first           # => "Nate"
@sorted_set.last            # => "Peter"
@sorted_set.revrange(0,2)   # => ["Peter", "Jeff", "Nate"]

@sorted_set['Newbie'] = 1
@sorted_set.members         # => ["Newbie", "Nate", "Jeff", "Peter"]
@sorted_set.members.reverse # => ["Peter", "Jeff", "Nate", "Newbie"]

@sorted_set.rangebyscore(10, 100, :limit => 2)   # => ["Nate", "Jeff"]
@sorted_set.members(:with_scores => true)        # => [["Newbie", 1], ["Nate", 16], ["Jeff", 28], ["Peter", 76]]

# atomic increment
@sorted_set.increment('Nate')
@sorted_set.incr('Peter')   # shorthand
@sorted_set.incr('Jeff', 4)