almicube 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +44 -0
  3. data/Rakefile +6 -0
  4. data/almicube.gemspec +3 -0
  5. data/lib/almicube/aggregator/base.rb +25 -0
  6. data/lib/almicube/aggregator/sum_aggregator.rb +23 -0
  7. data/lib/almicube/builder.rb +27 -30
  8. data/lib/almicube/bundler/base.rb +18 -0
  9. data/lib/almicube/bundler/days_ago_bundler.rb +22 -0
  10. data/lib/almicube/bundler/today_bundler.rb +9 -0
  11. data/lib/almicube/bundler/weekly_bundler.rb +11 -0
  12. data/lib/almicube/bundler/yesterday_bundler.rb +16 -0
  13. data/lib/almicube/cog.rb +11 -0
  14. data/lib/almicube/config.rb +40 -0
  15. data/lib/almicube/engine.rb +6 -0
  16. data/lib/almicube/key.rb +46 -0
  17. data/lib/almicube/model.rb +2 -5
  18. data/lib/almicube/proxy/association_proxy.rb +1 -1
  19. data/lib/almicube/ranking/base.rb +63 -0
  20. data/lib/almicube/ranking/data_ranking.rb +128 -0
  21. data/lib/almicube/ranking/sub_ranking.rb +51 -0
  22. data/lib/almicube/selector/all_selector.rb +18 -0
  23. data/lib/almicube/selector/base.rb +32 -0
  24. data/lib/almicube/selector/has_many_selector.rb +42 -0
  25. data/lib/almicube/selector/method_selector.rb +34 -0
  26. data/lib/almicube/version.rb +1 -1
  27. data/lib/almicube.rb +34 -4
  28. data/spec/almicube/aggregator/sum_aggregator_spec.rb +92 -0
  29. data/spec/almicube/builder_sprc.rb +22 -0
  30. data/spec/almicube/bundler/days_ago_bundler_spec.rb +20 -0
  31. data/spec/almicube/bundler/today_bundler_spec.rb +24 -0
  32. data/spec/almicube/bundler/yesterday_bundler_spec.rb +16 -0
  33. data/spec/almicube/config_spec.rb +46 -0
  34. data/spec/almicube/key_spec.rb +30 -0
  35. data/spec/almicube/ranking/base_spec.rb +9 -0
  36. data/spec/almicube/ranking/data_ranking_spec.rb +103 -0
  37. data/spec/almicube/ranking/sub_ranking_spec.rb +34 -0
  38. data/spec/almicube/selector/all_selector_spec.rb +22 -0
  39. data/spec/almicube/selector/method_selector_spec.rb +39 -0
  40. data/spec/almicube/selector/mock_spec.rb +34 -0
  41. data/spec/mocks/aggregator.rb +2 -0
  42. data/spec/mocks/bundler.rb +5 -0
  43. data/spec/mocks/model.rb +17 -0
  44. data/spec/mocks/selector.rb +9 -0
  45. data/spec/spec_helper.rb +11 -0
  46. data/spec/supports/shared_examples.rb +22 -0
  47. metadata +89 -7
  48. data/lib/almicube/builder/average_ranking_builder.rb +0 -35
  49. data/lib/almicube/builder/countable_ranking_builder.rb +0 -35
  50. data/lib/almicube/ranged_ranking.rb +0 -57
  51. data/lib/almicube/ranking.rb +0 -134
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5974ef075edf11c09d6e8c44485968661fcc8a5
4
- data.tar.gz: ff7ca640f98417dc29d755aa314a57a8ebefca42
3
+ metadata.gz: 3b5b3dee4cf2a4ca349f8b5d218fe23cbb6fbb7c
4
+ data.tar.gz: d5423d3770485d8176bd9cb0ac306e0ed2e32ac0
5
5
  SHA512:
6
- metadata.gz: 999950f31e8406189ebfce9726f6c5a6b99f7d4c389bb54e644dbcc9538d30c16e50169c449b35cbb86ce2cd3b3e214166a3c1acc0b2fd0b95d77d06c825f001
7
- data.tar.gz: ae64515586232c660796d417702a84e3d72907aa0f1e89563548a44c40d04617f56c653eaca9aedf74fed83ab555bcbbf15aa6316af3aa96ddb4abfbd06f8c05
6
+ metadata.gz: 86cc68a0f86730eb0d64e526dd49135265090574ac085ea3bbdf267940573cfd1f222abbf6b1eae7348b408684de7f204a0552b0927666850f0b61a0a2d29b04
7
+ data.tar.gz: a3d2279edd141c513f93a6e34ae80ab77089d7e01f2c7c354af3fa5ee048ca22e2eea82fa630e850787c78e77b23266e298ecdf2d7395ee12245633a6b12e986
data/Gemfile.lock ADDED
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ almicube (0.0.2)
5
+ activemodel (~> 4.0)
6
+ activesupport (~> 4.0)
7
+ redis (~> 3.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (4.1.0)
13
+ activesupport (= 4.1.0)
14
+ builder (~> 3.1)
15
+ activesupport (4.1.0)
16
+ i18n (~> 0.6, >= 0.6.9)
17
+ json (~> 1.7, >= 1.7.7)
18
+ minitest (~> 5.1)
19
+ thread_safe (~> 0.1)
20
+ tzinfo (~> 1.1)
21
+ builder (3.2.2)
22
+ diff-lcs (1.2.5)
23
+ i18n (0.6.9)
24
+ json (1.8.1)
25
+ minitest (5.3.3)
26
+ redis (3.0.7)
27
+ rspec (2.14.1)
28
+ rspec-core (~> 2.14.0)
29
+ rspec-expectations (~> 2.14.0)
30
+ rspec-mocks (~> 2.14.0)
31
+ rspec-core (2.14.8)
32
+ rspec-expectations (2.14.5)
33
+ diff-lcs (>= 1.1.3, < 2.0)
34
+ rspec-mocks (2.14.6)
35
+ thread_safe (0.3.3)
36
+ tzinfo (1.1.0)
37
+ thread_safe (~> 0.1)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ almicube!
44
+ rspec (~> 2.0)
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/almicube.gemspec CHANGED
@@ -19,4 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_dependency "redis", "~> 3.0"
21
21
  spec.add_dependency "activesupport", "~> 4.0"
22
+ spec.add_dependency "activemodel", "~> 4.0"
23
+
24
+ spec.add_development_dependency "rspec", "~> 2.0"
22
25
  end
@@ -0,0 +1,25 @@
1
+ module Almicube
2
+ module Aggregator
3
+ class Base
4
+ include Almicube::Cog
5
+
6
+ class << self
7
+ def connection
8
+ @redis ||= Almicube::Config.config.connection
9
+ end
10
+ end
11
+
12
+ def aggregate(ranking=nil)
13
+ self.ranking = ranking unless active? || ranking.nil?
14
+
15
+ self.ranking.selector.before_aggregate if self.ranking.selector.respond_to? :before_aggregate
16
+
17
+ if self.ranking.data?
18
+ data_aggregate self.ranking.key
19
+ else
20
+ sub_aggregate self.ranking.key
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module Almicube
2
+ module Aggregator
3
+ class SumAggregator < Base
4
+ protected
5
+
6
+ def data_aggregate(key)
7
+ ranking.records.each do |record|
8
+ value = record.send(ranking.attribute_name) if record.respond_to? ranking.attribute_name
9
+ value = ranking.default_score if value.nil?
10
+ self.class.connection.zadd(key, value, record.to_param)
11
+ end
12
+ end
13
+
14
+ def sub_aggregate(key)
15
+ keys = ranking.bundled_keys.select { |k| self.class.connection.zcard(k) > 0 }
16
+ keys << ranking.selector.interstore
17
+ if keys.length
18
+ self.class.connection.zinterstore(key, keys)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,41 +1,38 @@
1
1
  module Almicube
2
- module Builder
3
- class << self
4
- def instance(name, options={})
5
- raise ArgumentError, "invalid #1 name" unless has_builder? name
6
- builders[name].new options
7
- end
2
+ class Builder
3
+ attr_accessor :selector, :date, :bundler, :class_name, :attribute_name
8
4
 
9
- def register(name, builder_class)
10
- raise TypeError, 'invalid builder class' unless builder_class.kind_of? Builder::Base
11
- builders[name] = builder_class
12
- end
13
-
14
- def has_builder?(name)
15
- load_builder name
16
- builders.has_key? name
17
- end
5
+ def initialize(options={})
6
+ @class_name = options[:class_name]
7
+ @attribute_name = options[:attribute_name]
8
+ @selector = select_selector(options[:selector])
9
+ @bundler = select_bundler(options[:bundler])
10
+ @date = options[:date] || Date.today
11
+ end
18
12
 
19
- def builders
20
- @builders ||= {}
21
- end
13
+ def data(date=nil)
14
+ date ||= self.date
15
+ Almicube::Ranking::DataRanking.new options
16
+ end
22
17
 
23
- def load_builder(name)
24
- "Almicube::Builder::#{"#{name}_ranking_builder".classify}".constantize
25
- end
18
+ def options
19
+ { selector: selector,
20
+ bundler: bundler,
21
+ date: date,
22
+ class_name: class_name,
23
+ attribute_name: attribute_name }
26
24
  end
27
25
 
28
- module Base
29
- def self.included(base)
30
- base.include InstanceMethods
31
- end
26
+ protected
32
27
 
33
- def register(name)
34
- Builder.register(name, self)
35
- end
28
+ def select_selector(selector)
29
+ selector = selector.constantize if selector.is_a?(String) && Object.const_defined?(selector.to_s)
30
+ selector = selector.new if selector.is_a? Class
31
+ selector
32
+ end
36
33
 
37
- class InstanceMethods
38
- end
34
+ def select_bundler(bundler)
35
+ bundler
39
36
  end
40
37
  end
41
38
  end
@@ -0,0 +1,18 @@
1
+ module Almicube
2
+ module Bundler
3
+ class Base
4
+ include Almicube::Cog
5
+ attr_reader :name
6
+
7
+ def initialize(options={})
8
+ @name = options[:bundle] || options[:name]
9
+ end
10
+
11
+ alias :bundle :name
12
+
13
+ def keys
14
+ []
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Almicube
2
+ module Bundler
3
+ class DaysAgoBundler < Base
4
+ attr_reader :range
5
+
6
+ def initialize(options={})
7
+ @range = ( options[:range] || 1 ).to_i
8
+ options[:name] ||= :"#{range}-days-ago"
9
+ super options
10
+ end
11
+
12
+ def keys
13
+ return [] unless has_ranking?
14
+ range.times.map do |i|
15
+ key = ranking.data_key
16
+ key[:date] = key[:date] - (i+1).days
17
+ key
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ module Almicube
2
+ module Bundler
3
+ class TodayBundler < Base
4
+ def keys
5
+ []
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Almicube
2
+ module Bundler
3
+ class WeeklyBundler < DaysAgoBundler
4
+ def initialize(options={})
5
+ options[:range] = 7
6
+ options[:name] = :weekly
7
+ super(options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Almicube
2
+ module Bundler
3
+ class YesterdayBundler < Base
4
+ def initialize(options={})
5
+ options[:name] = :yesterday
6
+ super(options)
7
+ end
8
+
9
+ def keys
10
+ key = ranking.data_key
11
+ key[:date] = ranking.date - 1.days
12
+ [key]
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Almicube
2
+ module Cog
3
+ attr_accessor :ranking
4
+
5
+ def active?
6
+ ! @ranking.nil?
7
+ end
8
+
9
+ alias :has_ranking? :active?
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require 'active_model'
2
+
3
+ module Almicube
4
+ class Config
5
+ include ActiveModel::Model
6
+ attr_accessor :connection, :key_format
7
+
8
+ class << self
9
+ def root
10
+ Rails.root if defined? Rails
11
+ end
12
+
13
+ def filepath
14
+ @filepath ||= File.join(root.to_s, "config", "almicube.yml")
15
+ end
16
+
17
+ def config
18
+ if @instance.nil? && File.exists?(filepath)
19
+ @instance = self.new YAML.load_file(filepath)
20
+ end
21
+ @instance ||= self.new {}
22
+ end
23
+
24
+ def reset
25
+ @instance = nil
26
+ end
27
+ end
28
+
29
+ def connection(env = :default)
30
+ @connection ||= { default: nil }
31
+ raise ArgumentError, "connection does not exist" unless @connection.has_key? env
32
+ @redis ||= Redis.new @connection[env] unless @connection[env].nil?
33
+ @redis ||= Redis.new
34
+ end
35
+
36
+ def key_format
37
+ @key_format ||= '%{prefix}:%{class_name}:%{attribute_name}:%{type}:%{distinction}:%{suffix}'
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,6 @@
1
+ module Almicube
2
+ class Engine < ::Rails::Engine
3
+ config.autoload_paths += Dir[File.join("#{config.root}", "lib", "**")] if Rails.env.development?
4
+ puts config.autoload_paths
5
+ end
6
+ end
@@ -0,0 +1,46 @@
1
+ module Almicube
2
+ class Key
3
+
4
+ ALLOWED_OPTIONS = %i[prefix suffix class_name attribute_name type distinction date selector]
5
+ KEY_PATTERN = /%{([a-z_]+)}/ # Example) %{sample_key}
6
+
7
+ attr_reader :options, :ranking
8
+
9
+ attr_accessor :config
10
+
11
+ def initialize(ranking, options={})
12
+ @ranking = ranking
13
+ @options = ranking.options.merge(options).select { |k| self.class::ALLOWED_OPTIONS.include? k.to_sym }
14
+ @config ||= Config.config
15
+ end
16
+
17
+ def [](name)
18
+ options[name.to_sym]
19
+ end
20
+
21
+ def []=(name, value)
22
+ options[name.to_sym] = value if self.class::ALLOWED_OPTIONS.include? name.to_sym
23
+ end
24
+
25
+ def method_missing(m, *args, &block)
26
+ if to_str.respond_to? m
27
+ to_str.send(m, *args, &block)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def to_str
34
+ key = config.key_format.clone
35
+ key.match( self.class::KEY_PATTERN ) do |m|
36
+ value = options.fetch(m[1].to_sym, '')
37
+ value = value.strftime(options.fetch(:date_format, '%Y%m%d')) if value.is_a? Date
38
+ value = value.label if value.kind_of? Selector::Base
39
+ key.gsub! m[0], value.to_s
40
+ end while key =~ self.class::KEY_PATTERN
41
+ key
42
+ end
43
+
44
+ alias :to_s :to_str
45
+ end
46
+ end
@@ -10,16 +10,13 @@ module Almicube
10
10
  ranker = ranker.to_s
11
11
  options = options.symbolize_keys!.merge(class_name: self, attribute_name: ranker.to_sym)
12
12
 
13
- builder_name = options.delete :builder
14
- builder_name = :countable unless builder_name
15
-
16
13
  @ranking_builders ||= {}
17
- @ranking_builders[ranker.to_sym] = Almicube::Builder.instance(builder_name, options)
14
+ @ranking_builders[ranker.to_sym] = Almicube::Builder.new options
18
15
 
19
16
  class_eval <<-EVAL
20
17
  def self.#{ranker}_ranking(date = Date.today)
21
18
  @rankings ||= {}
22
- @rankings[:"#{ranker}:\#{date.to_s}"] ||= @ranking_builders[:#{ranker}].build(date)
19
+ @rankings[:"#{ranker}:\#{date.to_s}"] ||= @ranking_builders[:#{ranker}].data(date)
23
20
  end
24
21
 
25
22
  def #{ranker}_ranking(date = Date.today)
@@ -1,7 +1,7 @@
1
1
  module Almicube
2
2
  class AssociationProxy
3
3
  def initialize(ranking, item)
4
- raise TypeError, "without the Almicube::Ranking as #1 argument" unless ranking.kind_of? Ranking
4
+ raise TypeError, "without the Almicube::Ranking as #1 argument" unless ranking.kind_of? Ranking::Base
5
5
  @item = item
6
6
  @ranking = ranking
7
7
  end
@@ -0,0 +1,63 @@
1
+ module Almicube
2
+ module Ranking
3
+ class Base
4
+ attr_reader :selector, :bundler, :aggregator, :class_name, :date
5
+ attr_accessor :per_page
6
+
7
+ def initialize(options={})
8
+ @selector = options[:selector]
9
+ @aggregator = options[:aggregator] || Aggregator::SumAggregator.new
10
+ @bundler = options[:bundler]
11
+ @prefix = options[:prefix]
12
+ @suffix = options[:suffix]
13
+ @date = options[:date] || Date.today
14
+ @class_name = options[:class_name]
15
+ @class_name = @class_name.constantize if @class_name.is_a? String
16
+ @per_page = options[:per_page] || 10
17
+
18
+ @selector.ranking = self unless @selector.nil?
19
+ @aggregator.ranking = self unless @aggregator.nil?
20
+ @bundler.ranking = self unless @bundler.nil?
21
+ end
22
+
23
+ def records
24
+ selector.records
25
+ end
26
+
27
+ def bundled_keys
28
+ bundler.keys || []
29
+ end
30
+
31
+ def connection
32
+ Almicube::Config.config.connection
33
+ end
34
+
35
+ def page(page=1)
36
+ aggregate!
37
+ page = [1, page.to_i].max
38
+ revrange = connection.zrevrange(key, (page - 1) * per_page, page * per_page - 1)
39
+ records = class_name.where("id IN (?)", revrange).all
40
+ revrange.inject([]) { |l, v| l << records.detect { |r| r.to_param == v } }
41
+ end
42
+
43
+ def aggregate!(options = {})
44
+ @aggregator.aggregate self
45
+ end
46
+
47
+ def aggregate(options = {})
48
+ aggregate! options
49
+ true
50
+ rescue Exception => e
51
+ false
52
+ end
53
+
54
+ def data?
55
+ false
56
+ end
57
+
58
+ protected
59
+
60
+ attr_reader :prefix, :suffix
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,128 @@
1
+ require "redis"
2
+ require "active_support/all"
3
+
4
+ module Almicube
5
+ module Ranking
6
+ class DataRanking < Base
7
+ class << self
8
+ def default_options
9
+ { attribute_name: :score,
10
+ prefix: 'ranking',
11
+ suffix: '',
12
+ distinction: '%{date}',
13
+ date_format: '%Y%m%d',
14
+ date: Date.today,
15
+ per_page: 10,
16
+ as: Float,
17
+ default_score: 0,
18
+ class_name: nil }
19
+ end
20
+
21
+ def build(options={})
22
+ self.new options
23
+ end
24
+ end
25
+
26
+ def initialize(options={})
27
+ @options = self.class.default_options.merge options.symbolize_keys
28
+
29
+ raise TypeError, ":as option is only allowed Integer or Float" unless [Integer, Float].include? @options[:as]
30
+
31
+ super(@options)
32
+
33
+ @selector ||= Selector::AllSelector.new self.options
34
+ @options.delete(:selector)
35
+ @selector.ranking = self
36
+
37
+ @options[:aggregator] ||= Aggregator::SumAggregator.new
38
+ @options[:aggregator].ranking = self
39
+ end
40
+
41
+ KEY_PATTERN = /%{([a-z_]+)}/ # Example) %{sample_key}
42
+
43
+ def key(options={})
44
+ Almicube::Key.new self, options.merge( type: :data )
45
+ end
46
+
47
+ def data_key
48
+ key_format(@options[:data_key], @options.merge({ type: :data }))
49
+ end
50
+
51
+ def attribute_name
52
+ @options.fetch(:attribute_name, :score).to_s.to_sym
53
+ end
54
+
55
+ def date
56
+ @options.fetch(:date, Date.today)
57
+ end
58
+
59
+ def in(target)
60
+ association_name = class_name.to_s.underscore.pluralize
61
+
62
+ if ( target.class != class_name ) && target.respond_to?(association_name)
63
+ _selector = Selector::HasManySelector.new target: target, association_name: association_name
64
+ _selector.ranking = self
65
+ return SubRanking.new self, selector: _selector
66
+ end
67
+
68
+ self
69
+ end
70
+
71
+ def ranged(name)
72
+ SubRanking.new(self).ranged(name)
73
+ end
74
+
75
+ def per_page=(value)
76
+ @options[:per_page] = value
77
+ end
78
+
79
+ def options
80
+ @options.select{ |k| k != :type }.merge({ selector: selector, aggregator: aggregator })
81
+ end
82
+
83
+ def data?
84
+ selector.data_provider?
85
+ end
86
+
87
+ def exists?
88
+ connection.exists key
89
+ end
90
+
91
+ def default_score
92
+ @options.fetch(:default_score, 0)
93
+ end
94
+
95
+ def score(item)
96
+ actual_score = ( connection.zscore key, item.to_param ) || @options.fetch(:default_score, 0)
97
+ case @options[:as].to_s
98
+ when "Integer"
99
+ actual_score.to_i
100
+ when "Float"
101
+ actual_score.to_f
102
+ else
103
+ actual_score
104
+ end
105
+ end
106
+
107
+ def rank(item)
108
+ connection.zrevrank(key, item.to_param) + 1
109
+ end
110
+
111
+ def incr(item, score = 1)
112
+ connection.zincrby key, score, item.to_param
113
+ end
114
+
115
+ protected
116
+
117
+ def key_format(key_base, options)
118
+ key = key_base.to_s.clone
119
+ tmp_options = options.merge date: options.fetch(:date, Date.today).strftime(@options[:date_format])
120
+ tmp_options[:type] ||= :data
121
+ key.match( self.class::KEY_PATTERN ) do |m|
122
+ key.gsub! m[0], tmp_options.fetch(m[1].to_sym, '').to_s
123
+ end while key =~ self.class::KEY_PATTERN
124
+ key
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,51 @@
1
+ module Almicube
2
+ module Ranking
3
+ class SubRanking < Base
4
+ attr_reader :ranking, :bundler
5
+
6
+ def initialize(ranking, options={})
7
+ super(options)
8
+
9
+ @ranking = ranking
10
+ self.selector ||= ranking.selector
11
+ self.bundler = ( options[:bundler] || Almicube::Bundler::YesterdayBundler.new )
12
+ @class_name ||= ranking.class_name
13
+ end
14
+
15
+ def key
16
+ key = ranking.key
17
+ key[:type] = :built
18
+ key[:suffix] = suffix
19
+ key[:selector] = selector
20
+ key[:distinction] = "%{date}:in-%{selector}" unless selector.is_a? Selector::AllSelector
21
+ key
22
+ end
23
+
24
+ def data_key
25
+ ranking.key
26
+ end
27
+
28
+ def bundler=(value)
29
+ @bundler = value
30
+ value.ranking = self
31
+ end
32
+
33
+ def selector=(value)
34
+ @selector = value
35
+ value.ranking = self
36
+ end
37
+
38
+ def ranged(name)
39
+ bundler_class = "Almicube::Bundler::#{name.to_s.classify}Bundler".constantize
40
+ self.bundler = bundler_class.new if bundler_class.is_a? Class
41
+ self
42
+ end
43
+
44
+ protected
45
+
46
+ def suffix
47
+ bundler.bundle unless bundler.nil?
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ module Almicube
2
+ module Selector
3
+ class AllSelector < Base
4
+
5
+ def records
6
+ ranking.class_name.all
7
+ end
8
+
9
+ def label
10
+ :data
11
+ end
12
+
13
+ def data_provider?
14
+ true
15
+ end
16
+ end
17
+ end
18
+ end