Class: Almicube::Ranking
- Inherits:
-
Object
- Object
- Almicube::Ranking
- Defined in:
- lib/almicube/ranking.rb
Direct Known Subclasses
Constant Summary collapse
- KEY_PATTERN =
Example) %sample_key
/%{([a-z_]+)}/
Class Method Summary collapse
Instance Method Summary collapse
- #aggregate(options = {}) ⇒ Object
- #aggregate!(options = {}) ⇒ Object
- #all ⇒ Object
- #attribute_name ⇒ Object
- #date ⇒ Object
- #exists? ⇒ Boolean
- #incr(item, score = 1) ⇒ Object
-
#initialize(options = {}) ⇒ Ranking
constructor
A new instance of Ranking.
- #key ⇒ Object
- #page(page = 1) ⇒ Object
- #per_page ⇒ Object
- #per_page=(value) ⇒ Object
- #ranged(range) ⇒ Object
- #rank(item) ⇒ Object
- #score(item) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Ranking
Returns a new instance of Ranking.
29 30 31 32 33 |
# File 'lib/almicube/ranking.rb', line 29 def initialize(={}) = self.class..merge .symbolize_keys raise TypeError, ":as option is only allowed Integer or Float" unless [Integer, Float].include? [:as] end |
Class Method Details
.build(options = {}) ⇒ Object
24 25 26 |
# File 'lib/almicube/ranking.rb', line 24 def build(={}) self.new end |
.connection ⇒ Object
20 21 22 |
# File 'lib/almicube/ranking.rb', line 20 def connection @connection ||= Redis.new end |
.default_options ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/almicube/ranking.rb', line 7 def { attribute_name: :score, type: :data, prefix: 'ranking:%{type}', suffix: '%{attribute_name}', key: '%{prefix}:%{class_name}:%{date}:%{suffix}', date_format: '%Y%m%d', date: Date.today, per_page: 10, as: Float, default_score: 0 } end |
Instance Method Details
#aggregate(options = {}) ⇒ Object
83 84 85 86 87 88 |
# File 'lib/almicube/ranking.rb', line 83 def aggregate( = {}) aggregate! true rescue Exception => e false end |
#aggregate!(options = {}) ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/almicube/ranking.rb', line 72 def aggregate!( = {}) overwrite = !! ( .try(:overwrite) || false ) raise "ranking is already exists. if you want to force aggregating: set { overwrite: true }" if exists? && ! overwrite all.each do |record| score = .fetch(:default_score, 0) score = record.send attribute_name if record.respond_to? attribute_name connection.zadd key, score.to_f, record.to_param end end |
#all ⇒ Object
45 46 47 |
# File 'lib/almicube/ranking.rb', line 45 def all target_class.all end |
#attribute_name ⇒ Object
56 57 58 |
# File 'lib/almicube/ranking.rb', line 56 def attribute_name .fetch(:attribute_name, :score).to_s.to_sym end |
#date ⇒ Object
60 61 62 |
# File 'lib/almicube/ranking.rb', line 60 def date .fetch(:date, Date.today) end |
#exists? ⇒ Boolean
90 91 92 |
# File 'lib/almicube/ranking.rb', line 90 def exists? connection.exists key end |
#incr(item, score = 1) ⇒ Object
110 111 112 |
# File 'lib/almicube/ranking.rb', line 110 def incr(item, score = 1) connection.zincrby key, score, item.to_param end |
#key ⇒ Object
41 42 43 |
# File 'lib/almicube/ranking.rb', line 41 def key key_format([:key], ) end |
#page(page = 1) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/almicube/ranking.rb', line 49 def page(page=1) page = [1, page.to_i].max revrange = connection.zrevrange(key, (page - 1) * per_page, page * per_page - 1) records = target_class.find(revrange) revrange.inject([]) { |l, v| l << records.detect { |r| r.to_param == v } } end |
#per_page ⇒ Object
64 65 66 |
# File 'lib/almicube/ranking.rb', line 64 def per_page .fetch(:per_page, 0) end |
#per_page=(value) ⇒ Object
68 69 70 |
# File 'lib/almicube/ranking.rb', line 68 def per_page=(value) [:per_page] = value end |
#ranged(range) ⇒ Object
35 36 37 |
# File 'lib/almicube/ranking.rb', line 35 def ranged(range) Almicube::RangedRanking.new .merge( range: range, data_key: [:key] ).merge(Almicube::RangedRanking.overwrite_params) end |
#rank(item) ⇒ Object
106 107 108 |
# File 'lib/almicube/ranking.rb', line 106 def rank(item) connection.zrevrank(key, item.to_param) + 1 end |
#score(item) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/almicube/ranking.rb', line 94 def score(item) actual_score = ( connection.zscore key, item.to_param ) || .fetch(:default_score, 0) case [:as].to_s when "Integer" actual_score.to_i when "Float" actual_score.to_f else actual_score end end |