activerecord-reputation-system 1.4.0 → 1.5.0

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.
data/README.md CHANGED
@@ -70,9 +70,9 @@ Once reputation system is defined, evaluations for answers and questions can be
70
70
 
71
71
  Reputation value can be accessed as follow:
72
72
  ```ruby
73
- @answer.reputation_value_for(:avg_rating)
74
- @question.reputation_value_for(:votes)
75
- @user.reputation_value_for(:karma)
73
+ @answer.reptuation_for(:avg_rating)
74
+ @question.reptuation_for(:votes)
75
+ @user.reptuation_for(:karma)
76
76
  ```
77
77
 
78
78
  ## Defining Reputation System
@@ -134,7 +134,7 @@ decrease_evaluation(reputation_name, value, source)
134
134
  ## Reputation
135
135
  ```ruby
136
136
  # Returns the reputation value of the reputation with the given name.
137
- reputation_value_for(reputation_name)
137
+ reptuation_for(reputation_name)
138
138
 
139
139
  # Returns the reputation rank of the reputation with the given name.
140
140
  rank_for(reputation_name)
@@ -142,7 +142,7 @@ rank_for(reputation_name)
142
142
  # Returns the normalized reputation value of the reputation with the given name. The normalization is computed using the following equation (assuming linear distribution):
143
143
  # normalized_value = (x - min) / (max - min) if max - min is not 0
144
144
  # normalized_value = 1 if max - min is 0
145
- normalized_reputation_value_for(reputation_name)
145
+ normalized_reptuation_for(reputation_name)
146
146
 
147
147
  # Activates all reputations in the record. Active reputations are used when computing ranks or normalized reputation values.
148
148
  activate_all_reputations
@@ -213,7 +213,7 @@ add_evaluation(:reputation_name, evaluation_value, source, :scope)
213
213
  ```
214
214
  Also, reputations can be accessed in the context of scopes:
215
215
  ```ruby
216
- reputation_value_for(:reputation_name, :scope)
216
+ reptuation_for(:reputation_name, :scope)
217
217
  ```
218
218
  To use a scoped reputation as a source in another reputation, try this:
219
219
  ```ruby
@@ -21,15 +21,19 @@ class RSEvaluation < ActiveRecord::Base
21
21
 
22
22
  attr_accessible :reputation_name, :value, :source, :source_id, :source_type, :target, :target_id, :target_type
23
23
 
24
+ # Sets an appropriate source type in case of Single Table Inheritance.
25
+ before_validation :set_source_type_for_sti
26
+
24
27
  # the same source cannot evaluate the same target more than once.
25
28
  validates_uniqueness_of :source_id, :scope => [:reputation_name, :source_type, :target_id, :target_type]
26
29
  validate :source_must_be_defined_for_reputation_in_network
27
30
 
28
31
  def self.find_by_reputation_name_and_source_and_target(reputation_name, source, target)
32
+ source_type = get_source_type_for_sti(source, target.class.name, reputation_name)
29
33
  RSEvaluation.find(:first,
30
34
  :conditions => {:reputation_name => reputation_name.to_s,
31
35
  :source_id => source.id,
32
- :source_type => source.class.name,
36
+ :source_type => source_type,
33
37
  :target_id => target.id,
34
38
  :target_type => target.class.name
35
39
  })
@@ -43,6 +47,20 @@ class RSEvaluation < ActiveRecord::Base
43
47
 
44
48
  protected
45
49
 
50
+ def self.get_source_type_for_sti(source, target_type, reputation_name)
51
+ valid_source_type = ReputationSystem::Network.get_reputation_def(target_type, reputation_name)[:source].to_s.camelize
52
+ temp = source.class
53
+ while temp && valid_source_type != temp.name && temp.name != "ActiveRecord::Base"
54
+ temp = temp.superclass
55
+ end
56
+ temp ? temp.name : nil
57
+ end
58
+
59
+ def set_source_type_for_sti
60
+ temp = self.class.get_source_type_for_sti(source, target_type, reputation_name)
61
+ self.source_type = temp if temp
62
+ end
63
+
46
64
  def source_must_be_defined_for_reputation_in_network
47
65
  unless source_type == ReputationSystem::Network.get_reputation_def(target_type, reputation_name)[:source].to_s.camelize
48
66
  errors.add(:source_type, "#{source_type} is not source of #{reputation_name} reputation")
@@ -25,6 +25,7 @@ class RSReputation < ActiveRecord::Base
25
25
 
26
26
  attr_accessible :reputation_name, :value, :aggregated_by, :active, :target, :target_id, :target_type, :received_messages
27
27
 
28
+ before_validation :set_target_type_for_sti
28
29
  before_save :change_zero_value_in_case_of_product_process
29
30
 
30
31
  VALID_PROCESSES = ['sum', 'average', 'product']
@@ -32,7 +33,8 @@ class RSReputation < ActiveRecord::Base
32
33
  validates_uniqueness_of :reputation_name, :scope => [:target_id, :target_type]
33
34
 
34
35
  def self.find_by_reputation_name_and_target(reputation_name, target)
35
- RSReputation.find_by_reputation_name_and_target_id_and_target_type(reputation_name.to_s, target.id, target.class.name)
36
+ target_type = get_target_type_for_sti(target, reputation_name)
37
+ RSReputation.find_by_reputation_name_and_target_id_and_target_type(reputation_name.to_s, target.id, target_type)
36
38
  end
37
39
 
38
40
  # All external access to reputation should use this since they are created lazily.
@@ -176,6 +178,21 @@ class RSReputation < ActiveRecord::Base
176
178
  :conditions => {:reputation_name => reputation_name.to_s, :target_type => target_type, :active => true})
177
179
  end
178
180
 
181
+ def self.get_target_type_for_sti(target, reputation_name)
182
+ temp = target.class
183
+ defs = ReputationSystem::Network.get_reputation_defs(temp.name)[reputation_name.to_sym]
184
+ while temp && temp.name != "ActiveRecord::Base" && defs && defs.empty?
185
+ temp = temp.superclass
186
+ defs = ReputationSystem::Network.get_reputation_defs(temp.name)[reputation_name.to_sym]
187
+ end
188
+ temp ? temp.name : nil
189
+ end
190
+
191
+ def set_target_type_for_sti
192
+ temp = self.class.get_target_type_for_sti(target, reputation_name)
193
+ self.target_type = temp if temp
194
+ end
195
+
179
196
  def change_zero_value_in_case_of_product_process
180
197
  self.value = 1 if self.value == 0 && self.aggregated_by == "product"
181
198
  end
@@ -18,8 +18,8 @@ module ReputationSystem
18
18
  class Network
19
19
  class << self
20
20
  def has_reputation_for?(class_name, reputation_name)
21
- reputation_defs = get_reputation_defs(class_name)
22
- reputation_defs[reputation_name.to_sym] && reputation_defs[reputation_name.to_sym][:source]
21
+ reputation_def = get_reputation_def(class_name, reputation_name)
22
+ !!reputation_def[:source]
23
23
  end
24
24
 
25
25
  def get_reputation_defs(class_name)
@@ -27,8 +27,21 @@ module ReputationSystem
27
27
  end
28
28
 
29
29
  def get_reputation_def(class_name, reputation_name)
30
- reputation_defs = get_reputation_defs(class_name)
31
- reputation_defs[reputation_name.to_sym] ||= {}
30
+ reputation_def = {}
31
+ unless class_name == "ActiveRecord::Base"
32
+ reputation_defs = get_reputation_defs(class_name)
33
+ reputation_defs[reputation_name.to_sym] ||= {}
34
+ reputation_def = reputation_defs[reputation_name.to_sym]
35
+ if reputation_def == {}
36
+ begin
37
+ klass = class_name.constantize.superclass
38
+ reputation_def = get_reputation_def(klass.name, reputation_name) if klass
39
+ rescue NameError
40
+ # Class might have not been initialized yet at this point.
41
+ end
42
+ end
43
+ end
44
+ reputation_def
32
45
  end
33
46
 
34
47
  def add_reputation_def(class_name, reputation_name, options)
@@ -17,10 +17,20 @@
17
17
  module ReputationSystem
18
18
  module Reputation
19
19
  def reputation_value_for(reputation_name, *args)
20
+ warn "[DEPRECATION] `reputation_value_for` will be deprecated in version 2.0.0. Please use `reputation_for` instead."
21
+ reputation_for(reputation_name, *args)
22
+ end
23
+
24
+ def reputation_for(reputation_name, *args)
20
25
  find_reputation(reputation_name, args.first).value
21
26
  end
22
27
 
23
28
  def normalized_reputation_value_for(reputation_name, *args)
29
+ warn "[DEPRECATION] `normalized_reputation_value_for` will be deprecated in version 2.0.0. Please use `normalized_reputation_for` instead."
30
+ normalized_reputation_for(reputation_name, *args)
31
+ end
32
+
33
+ def normalized_reputation_for(reputation_name, *args)
24
34
  find_reputation(reputation_name, args.first).normalized_value
25
35
  end
26
36
 
@@ -45,7 +55,7 @@ module ReputationSystem
45
55
 
46
56
  def rank_for(reputation_name, *args)
47
57
  scope = args.first
48
- my_value = self.reputation_value_for(reputation_name, scope)
58
+ my_value = self.reputation_for(reputation_name, scope)
49
59
  self.class.count_with_reputation(reputation_name, scope, :all,
50
60
  :conditions => ["rs_reputations.value > ?", my_value]
51
61
  ) + 1
@@ -15,5 +15,5 @@
15
15
  ##
16
16
 
17
17
  module ReputationSystem
18
- VERSION = "1.4.0"
18
+ VERSION = "1.5.0"
19
19
  end
@@ -32,6 +32,24 @@ describe RSEvaluation do
32
32
  end
33
33
  end
34
34
 
35
+ context "Callback" do
36
+ describe "#set_source_type_for_sti" do
37
+ it "should assign source class name as source type if not STI" do
38
+ question = Question.create!(:text => 'Does this work?', :author_id => @user.id)
39
+ question.add_evaluation(:total_votes, 5, @user)
40
+ evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(:total_votes, @user, question)
41
+ evaluation.source_type.should == @user.class.name
42
+ end
43
+ it "should assign source's ancestors class name where reputation is declared if STI" do
44
+ designer = Designer.create! :name => 'hiro'
45
+ programmer = Programmer.create! :name => 'katsuya'
46
+ programmer.add_evaluation(:leadership, 1, designer)
47
+ evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(:leadership, designer, programmer)
48
+ evaluation.source_type.should == Person.name
49
+ end
50
+ end
51
+ end
52
+
35
53
  context "Association" do
36
54
  it "should delete associated reputation message" do
37
55
  @question.add_evaluation(:total_votes, 5, @user)
@@ -56,6 +56,24 @@ describe RSReputation do
56
56
  end
57
57
  end
58
58
 
59
+ context "Callback" do
60
+ describe "#set_target_type_for_sti" do
61
+ it "should assign target class name as target type if not STI" do
62
+ question = Question.create!(:text => 'Does this work?', :author_id => @user.id)
63
+ question.add_evaluation(:total_votes, 5, @user)
64
+ rep = RSReputation.find_by_reputation_name_and_target(:total_votes, question)
65
+ rep.target_type.should == question.class.name
66
+ end
67
+ it "should assign target's ancestors class name where reputation is declared if STI" do
68
+ designer = Designer.create! :name => 'hiro'
69
+ programmer = Programmer.create! :name => 'katsuya'
70
+ programmer.add_evaluation(:leadership, 1, designer)
71
+ rep = RSReputation.find_by_reputation_name_and_target(:leadership, programmer)
72
+ rep.target_type.should == Person.name
73
+ end
74
+ end
75
+ end
76
+
59
77
  context "Association" do
60
78
  before :each do
61
79
  @question = Question.create!(:text => 'What is Twitter?', :author_id => @user.id)
@@ -36,14 +36,14 @@ describe ActiveRecord::Base do
36
36
  @user.respond_to?(:add_evaluation).should == false
37
37
  end
38
38
 
39
- it "should add 'reputation_value_for' method to a model with reputation" do
40
- @user.respond_to?(:reputation_value_for).should == true
41
- @question.respond_to?(:reputation_value_for).should == true
39
+ it "should add 'reputation_for' method to a model with reputation" do
40
+ @user.respond_to?(:reputation_for).should == true
41
+ @question.respond_to?(:reputation_for).should == true
42
42
  end
43
43
 
44
- it "should add 'normalized_reputation_value_for' method to a model with reputation" do
45
- @user.respond_to?(:normalized_reputation_value_for).should == true
46
- @question.respond_to?(:normalized_reputation_value_for).should == true
44
+ it "should add 'normalized_reputation_for' method to a model with reputation" do
45
+ @user.respond_to?(:normalized_reputation_for).should == true
46
+ @question.respond_to?(:normalized_reputation_for).should == true
47
47
  end
48
48
 
49
49
  it "should delete reputations if target is deleted" do
@@ -56,12 +56,12 @@ describe ActiveRecord::Base do
56
56
  end
57
57
 
58
58
  it "should have declared default value if any" do
59
- @answer.reputation_value_for(:avg_rating).should == 1
59
+ @answer.reputation_for(:avg_rating).should == 1
60
60
  end
61
61
 
62
62
  it "should overwrite reputation definitions if the same reputation name is declared" do
63
63
  Answer.has_reputation(:avg_rating, :source => :user, :aggregated_by => :average, :init_value => 2)
64
- Answer.new.reputation_value_for(:avg_rating).should == 2
64
+ Answer.new.reputation_for(:avg_rating).should == 2
65
65
  end
66
66
  end
67
67
  end
@@ -75,7 +75,7 @@ describe ActiveRecord::Base do
75
75
  describe "#add_evaluation" do
76
76
  it "should create evaluation in case of valid input" do
77
77
  @question.add_evaluation(:total_votes, 1, @user).should be_true
78
- @question.reputation_value_for(:total_votes).should == 1
78
+ @question.reputation_for(:total_votes).should == 1
79
79
  end
80
80
 
81
81
  it "should raise exception if invalid reputation name is given" do
@@ -96,9 +96,9 @@ describe ActiveRecord::Base do
96
96
  it "should add evaluation on appropriate scope" do
97
97
  @phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be_true
98
98
  @phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be_true
99
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 1
100
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 2
101
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
99
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 1
100
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 2
101
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
102
102
  end
103
103
 
104
104
  it "should raise exception if invalid scope is given" do
@@ -114,22 +114,22 @@ describe ActiveRecord::Base do
114
114
  describe "#add_or_update_evaluation" do
115
115
  it "should create evaluation if it does not exist" do
116
116
  @question.add_or_update_evaluation(:total_votes, 1, @user).should be_true
117
- @question.reputation_value_for(:total_votes).should == 1
117
+ @question.reputation_for(:total_votes).should == 1
118
118
  end
119
119
 
120
120
  it "should update evaluation if it exists already" do
121
121
  @question.add_evaluation(:total_votes, 1, @user)
122
122
  @question.add_or_update_evaluation(:total_votes, 2, @user).should be_true
123
- @question.reputation_value_for(:total_votes).should == 2
123
+ @question.reputation_for(:total_votes).should == 2
124
124
  end
125
125
 
126
126
  context "With Scopes" do
127
127
  it "should add evaluation on appropriate scope if it does not exist" do
128
128
  @phrase.add_or_update_evaluation(:difficulty_with_scope, 1, @user, :s1).should be_true
129
129
  @phrase.add_or_update_evaluation(:difficulty_with_scope, 2, @user, :s2).should be_true
130
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 1
131
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 2
132
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
130
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 1
131
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 2
132
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
133
133
  end
134
134
 
135
135
  it "should update evaluation on appropriate scope if it exists already" do
@@ -137,9 +137,9 @@ describe ActiveRecord::Base do
137
137
  @phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be_true
138
138
  @phrase.add_or_update_evaluation(:difficulty_with_scope, 3, @user, :s1).should be_true
139
139
  @phrase.add_or_update_evaluation(:difficulty_with_scope, 5, @user, :s2).should be_true
140
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 3
141
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 5
142
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
140
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 3
141
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 5
142
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
143
143
  end
144
144
  end
145
145
  end
@@ -151,7 +151,7 @@ describe ActiveRecord::Base do
151
151
 
152
152
  it "should update evaluation in case of valid input" do
153
153
  @question.update_evaluation(:total_votes, 2, @user).should be_true
154
- @question.reputation_value_for(:total_votes).should == 2
154
+ @question.reputation_for(:total_votes).should == 2
155
155
  end
156
156
 
157
157
  it "should raise exception if invalid reputation name is given" do
@@ -173,9 +173,9 @@ describe ActiveRecord::Base do
173
173
 
174
174
  it "should update evaluation on appropriate scope" do
175
175
  @phrase.update_evaluation(:difficulty_with_scope, 5, @user, :s2).should be_true
176
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 0
177
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 5
178
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
176
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
177
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 5
178
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
179
179
  end
180
180
 
181
181
  it "should raise exception if invalid scope is given" do
@@ -195,7 +195,7 @@ describe ActiveRecord::Base do
195
195
 
196
196
  it "should delete evaluation in case of valid input" do
197
197
  @question.delete_evaluation!(:total_votes, @user)
198
- @question.reputation_value_for(:total_votes).should == 0
198
+ @question.reputation_for(:total_votes).should == 0
199
199
  end
200
200
 
201
201
  it "should raise exception if invalid reputation name is given" do
@@ -217,9 +217,9 @@ describe ActiveRecord::Base do
217
217
 
218
218
  it "should delete evaluation on appropriate scope" do
219
219
  @phrase.delete_evaluation!(:difficulty_with_scope, @user, :s2)
220
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 0
221
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 0
222
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
220
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
221
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 0
222
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
223
223
  end
224
224
 
225
225
  it "should raise exception if invalid scope is given" do
@@ -239,7 +239,7 @@ describe ActiveRecord::Base do
239
239
 
240
240
  it "should delete evaluation in case of valid input" do
241
241
  @question.delete_evaluation(:total_votes, @user).should be_true
242
- @question.reputation_value_for(:total_votes).should == 0
242
+ @question.reputation_for(:total_votes).should == 0
243
243
  end
244
244
 
245
245
  it "should raise exception if invalid reputation name is given" do
@@ -257,9 +257,9 @@ describe ActiveRecord::Base do
257
257
 
258
258
  it "should delete evaluation on appropriate scope" do
259
259
  @phrase.delete_evaluation(:difficulty_with_scope, @user, :s2).should be_true
260
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 0
261
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 0
262
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
260
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
261
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 0
262
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
263
263
  end
264
264
 
265
265
  it "should raise exception if invalid scope is given" do
@@ -275,13 +275,13 @@ describe ActiveRecord::Base do
275
275
  describe "#increase_evaluation" do
276
276
  it "should add evaluation if it does not exist" do
277
277
  @question.increase_evaluation(:total_votes, 2, @user).should be_true
278
- @question.reputation_value_for(:total_votes).should == 2
278
+ @question.reputation_for(:total_votes).should == 2
279
279
  end
280
280
 
281
281
  it "should increase evaluation if it exists already" do
282
282
  @question.add_evaluation(:total_votes, 1, @user)
283
283
  @question.increase_evaluation(:total_votes, 2, @user).should be_true
284
- @question.reputation_value_for(:total_votes).should == 3
284
+ @question.reputation_for(:total_votes).should == 3
285
285
  end
286
286
 
287
287
  context "With Scopes" do
@@ -291,9 +291,9 @@ describe ActiveRecord::Base do
291
291
 
292
292
  it "should increase evaluation on appropriate scope" do
293
293
  @phrase.increase_evaluation(:difficulty_with_scope, 5, @user, :s2).should be_true
294
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 0
295
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == 7
296
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
294
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
295
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == 7
296
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
297
297
  end
298
298
  end
299
299
  end
@@ -301,13 +301,13 @@ describe ActiveRecord::Base do
301
301
  describe "#decrease_evaluation" do
302
302
  it "should add evaluation if it does not exist" do
303
303
  @question.decrease_evaluation(:total_votes, 2, @user).should be_true
304
- @question.reputation_value_for(:total_votes).should == -2
304
+ @question.reputation_for(:total_votes).should == -2
305
305
  end
306
306
 
307
307
  it "should increase evaluation if it exists already" do
308
308
  @question.add_evaluation(:total_votes, 1, @user)
309
309
  @question.decrease_evaluation(:total_votes, 2, @user).should be_true
310
- @question.reputation_value_for(:total_votes).should == -1
310
+ @question.reputation_for(:total_votes).should == -1
311
311
  end
312
312
 
313
313
  context "With Scopes" do
@@ -317,9 +317,9 @@ describe ActiveRecord::Base do
317
317
 
318
318
  it "should decrease evaluation on appropriate scope" do
319
319
  @phrase.decrease_evaluation(:difficulty_with_scope, 5, @user, :s2).should be_true
320
- @phrase.reputation_value_for(:difficulty_with_scope, :s1).should == 0
321
- @phrase.reputation_value_for(:difficulty_with_scope, :s2).should == -3
322
- @phrase.reputation_value_for(:difficulty_with_scope, :s3).should == 0
320
+ @phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
321
+ @phrase.reputation_for(:difficulty_with_scope, :s2).should == -3
322
+ @phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
323
323
  end
324
324
  end
325
325
  end
@@ -336,8 +336,8 @@ describe ActiveRecord::Base do
336
336
  it "should affect only reputations with relevant scope" do
337
337
  @trans_ja.add_evaluation(:votes, 1, @user)
338
338
  @trans_fr.add_evaluation(:votes, 2, @user)
339
- @phrase.reputation_value_for(:maturity, :ja).should == 1
340
- @phrase.reputation_value_for(:maturity, :fr).should == 2
339
+ @phrase.reputation_for(:maturity, :ja).should == 1
340
+ @phrase.reputation_for(:maturity, :fr).should == 2
341
341
  end
342
342
  end
343
343
 
@@ -348,8 +348,8 @@ describe ActiveRecord::Base do
348
348
 
349
349
  it "should affect only reputations with relevant scope" do
350
350
  @trans_ja.update_evaluation(:votes, 3, @user)
351
- @phrase.reputation_value_for(:maturity, :ja).should == 3
352
- @phrase.reputation_value_for(:maturity, :fr).should == 0
351
+ @phrase.reputation_for(:maturity, :ja).should == 3
352
+ @phrase.reputation_for(:maturity, :fr).should == 0
353
353
  end
354
354
  end
355
355
 
@@ -360,8 +360,8 @@ describe ActiveRecord::Base do
360
360
 
361
361
  it "should affect only reputations with relevant scope" do
362
362
  @trans_ja.delete_evaluation!(:votes, @user)
363
- @phrase.reputation_value_for(:maturity, :ja).should == 0
364
- @phrase.reputation_value_for(:maturity, :fr).should == 0
363
+ @phrase.reputation_for(:maturity, :ja).should == 0
364
+ @phrase.reputation_for(:maturity, :fr).should == 0
365
365
  end
366
366
  end
367
367
  end
@@ -378,14 +378,14 @@ describe ActiveRecord::Base do
378
378
  describe "#add_evaluation" do
379
379
  it "should affect only reputations with relevant scope" do
380
380
  @trans_ja.add_evaluation(:votes, 1, @user)
381
- @phrase.reputation_value_for(:maturity_all).should == 1
381
+ @phrase.reputation_for(:maturity_all).should == 1
382
382
  @trans_fr.add_evaluation(:votes, 2, @user)
383
- @phrase.reputation_value_for(:maturity_all).should == 3
383
+ @phrase.reputation_for(:maturity_all).should == 3
384
384
  @trans_de.add_evaluation(:votes, 3, @user)
385
- @phrase.reputation_value_for(:maturity_all).should == 3
386
- @phrase.reputation_value_for(:maturity, :ja).should == 1
387
- @phrase.reputation_value_for(:maturity, :fr).should == 2
388
- @phrase.reputation_value_for(:maturity, :de).should == 3
385
+ @phrase.reputation_for(:maturity_all).should == 3
386
+ @phrase.reputation_for(:maturity, :ja).should == 1
387
+ @phrase.reputation_for(:maturity, :fr).should == 2
388
+ @phrase.reputation_for(:maturity, :de).should == 3
389
389
  end
390
390
  end
391
391
 
@@ -398,7 +398,7 @@ describe ActiveRecord::Base do
398
398
  it "should affect only reputations with relevant scope" do
399
399
  @trans_ja.update_evaluation(:votes, 3, @user)
400
400
  @trans_de.update_evaluation(:votes, 2, @user)
401
- @phrase.reputation_value_for(:maturity_all).should == 3
401
+ @phrase.reputation_for(:maturity_all).should == 3
402
402
  end
403
403
  end
404
404
 
@@ -410,9 +410,9 @@ describe ActiveRecord::Base do
410
410
 
411
411
  it "should affect only reputations with relevant scope" do
412
412
  @trans_de.delete_evaluation!(:votes, @user)
413
- @phrase.reputation_value_for(:maturity_all).should == 1
413
+ @phrase.reputation_for(:maturity_all).should == 1
414
414
  @trans_ja.delete_evaluation!(:votes, @user)
415
- @phrase.reputation_value_for(:maturity_all).should == 0
415
+ @phrase.reputation_for(:maturity_all).should == 0
416
416
  end
417
417
  end
418
418
  end
@@ -26,28 +26,28 @@ describe ActiveRecord::Base do
26
26
  end
27
27
 
28
28
  context "Primary Reputation" do
29
- describe "#reputation_value_for" do
29
+ describe "#reputation_for" do
30
30
  it "should return 0 as a default" do
31
- @question.reputation_value_for(:total_votes).should == 0
31
+ @question.reputation_for(:total_votes).should == 0
32
32
  end
33
33
 
34
34
  it "should return appropriate value in case of valid input" do
35
35
  user2 = User.new(:name => 'dick')
36
36
  @question.add_evaluation(:total_votes, 1, @user)
37
37
  @question.add_evaluation(:total_votes, 1, user2)
38
- @question.reputation_value_for(:total_votes).should == 2
38
+ @question.reputation_for(:total_votes).should == 2
39
39
  end
40
40
 
41
41
  it "should raise exception if invalid reputation name is given" do
42
- lambda {@question.reputation_value_for(:invalid)}.should raise_error(ArgumentError)
42
+ lambda {@question.reputation_for(:invalid)}.should raise_error(ArgumentError)
43
43
  end
44
44
 
45
45
  it "should raise exception if scope is given for reputation with no scopes" do
46
- lambda {@question.reputation_value_for(:difficulty, :s1)}.should raise_error(ArgumentError)
46
+ lambda {@question.reputation_for(:difficulty, :s1)}.should raise_error(ArgumentError)
47
47
  end
48
48
 
49
49
  it "should raise exception if scope is not given for reputation with scopes" do
50
- lambda {@phrase.reputation_value_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
50
+ lambda {@phrase.reputation_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
51
51
  end
52
52
  end
53
53
 
@@ -83,20 +83,20 @@ describe ActiveRecord::Base do
83
83
  end
84
84
 
85
85
  context "Non-Primary Reputation with Gathering Aggregation" do
86
- describe "#reputation_value_for" do
86
+ describe "#reputation_for" do
87
87
  it "should always have correct updated value" do
88
88
  question2 = Question.create!(:text => 'Does this work?', :author_id => @user.id)
89
- @user.reputation_value_for(:question_karma).should == 0
89
+ @user.reputation_for(:question_karma).should == 0
90
90
  @question.add_evaluation(:total_votes, 1, @user)
91
- @user.reputation_value_for(:question_karma).should == 1
91
+ @user.reputation_for(:question_karma).should == 1
92
92
  question2.add_evaluation(:total_votes, 1, @user)
93
- @user.reputation_value_for(:question_karma).should == 2
93
+ @user.reputation_for(:question_karma).should == 2
94
94
  end
95
95
  end
96
96
  end
97
97
 
98
98
  context "Non-Primary Reputation with Mixing Aggregation" do
99
- describe "#reputation_value_for" do
99
+ describe "#reputation_for" do
100
100
  it "should always have correct updated value" do
101
101
  question = Question.create!(:text => 'Does this work?', :author_id => @user.id)
102
102
  question2 = Question.create!(:text => 'Does this work?', :author_id => @user.id)
@@ -108,19 +108,19 @@ describe ActiveRecord::Base do
108
108
  answer2 = Answer.create!(:text => 'Yes!', :author_id => @user.id, :question_id => question2.id)
109
109
  answer.add_evaluation(:avg_rating, 3, @user)
110
110
  answer2.add_evaluation(:avg_rating, 2, @user)
111
- answer.reputation_value_for(:weighted_avg_rating).should == 3
112
- answer2.reputation_value_for(:weighted_avg_rating).should == 4
113
- @user.reputation_value_for(:answer_karma).should be_within(DELTA).of(3.5)
114
- @user.reputation_value_for(:question_karma).should be_within(DELTA).of(2)
115
- @user.reputation_value_for(:karma).should be_within(DELTA).of(1.4)
111
+ answer.reputation_for(:weighted_avg_rating).should == 3
112
+ answer2.reputation_for(:weighted_avg_rating).should == 4
113
+ @user.reputation_for(:answer_karma).should be_within(DELTA).of(3.5)
114
+ @user.reputation_for(:question_karma).should be_within(DELTA).of(2)
115
+ @user.reputation_for(:karma).should be_within(DELTA).of(1.4)
116
116
  end
117
117
  end
118
118
  end
119
119
 
120
120
  context "Normalization" do
121
- describe "#normalized_reputation_value_for" do
121
+ describe "#normalized_reputation_for" do
122
122
  it "should return 0 as if there is no data" do
123
- @question.normalized_reputation_value_for(:total_votes).should == 0
123
+ @question.normalized_reputation_for(:total_votes).should == 0
124
124
  end
125
125
 
126
126
  it "should return appropriate value in case of valid input" do
@@ -129,21 +129,21 @@ describe ActiveRecord::Base do
129
129
  @question.add_evaluation(:total_votes, 1, @user)
130
130
  question2.add_evaluation(:total_votes, 2, @user)
131
131
  question3.add_evaluation(:total_votes, 3, @user)
132
- @question.normalized_reputation_value_for(:total_votes).should == 0
133
- question2.normalized_reputation_value_for(:total_votes).should == 0.5
134
- question3.normalized_reputation_value_for(:total_votes).should == 1
132
+ @question.normalized_reputation_for(:total_votes).should == 0
133
+ question2.normalized_reputation_for(:total_votes).should == 0.5
134
+ question3.normalized_reputation_for(:total_votes).should == 1
135
135
  end
136
136
 
137
137
  it "should raise exception if invalid reputation name is given" do
138
- lambda {@question.normalized_reputation_value_for(:invalid)}.should raise_error(ArgumentError)
138
+ lambda {@question.normalized_reputation_for(:invalid)}.should raise_error(ArgumentError)
139
139
  end
140
140
 
141
141
  it "should raise exception if scope is given for reputation with no scopes" do
142
- lambda {@question.normalized_reputation_value_for(:difficulty, :s1)}.should raise_error(ArgumentError)
142
+ lambda {@question.normalized_reputation_for(:difficulty, :s1)}.should raise_error(ArgumentError)
143
143
  end
144
144
 
145
145
  it "should raise exception if scope is not given for reputation with scopes" do
146
- lambda {@phrase.normalized_reputation_value_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
146
+ lambda {@phrase.normalized_reputation_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
147
147
  end
148
148
  end
149
149
 
@@ -29,7 +29,7 @@ describe ActiveRecord::Base do
29
29
  it "should add scope if the reputation has scopes defined" do
30
30
  Phrase.add_scope_for(:difficulty_with_scope, :s4)
31
31
  @phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s4)
32
- @phrase.reputation_value_for(:difficulty_with_scope, :s4).should == 2
32
+ @phrase.reputation_for(:difficulty_with_scope, :s4).should == 2
33
33
  end
34
34
 
35
35
  it "should raise exception if the scope already exist" do
@@ -40,4 +40,4 @@ describe ActiveRecord::Base do
40
40
  lambda{Question.add_scope_for(:difficulty, :s1)}.should raise_error(ArgumentError)
41
41
  end
42
42
  end
43
- end
43
+ end
data/spec/spec_helper.rb CHANGED
@@ -102,6 +102,12 @@ ActiveRecord::Schema.define do
102
102
  t.string :locale
103
103
  t.timestamps
104
104
  end
105
+
106
+ create_table :people do |t|
107
+ t.string :name
108
+ t.string :type
109
+ t.timestamps
110
+ end
105
111
  end
106
112
 
107
113
  class User < ActiveRecord::Base
@@ -110,16 +116,16 @@ class User < ActiveRecord::Base
110
116
 
111
117
  has_reputation :karma,
112
118
  :source => [
113
- {:reputation => :question_karma},
114
- {:reputation => :answer_karma, :weight => 0.2}],
119
+ { :reputation => :question_karma },
120
+ { :reputation => :answer_karma, :weight => 0.2 }],
115
121
  :aggregated_by => :product
116
122
 
117
123
  has_reputation :question_karma,
118
- :source => {:reputation => :total_votes, :of => :questions},
124
+ :source => { :reputation => :total_votes, :of => :questions },
119
125
  :aggregated_by => :sum
120
126
 
121
127
  has_reputation :answer_karma,
122
- :source => {:reputation => :weighted_avg_rating, :of => :answers},
128
+ :source => { :reputation => :weighted_avg_rating, :of => :answers },
123
129
  :aggregated_by => :average
124
130
  end
125
131
 
@@ -130,7 +136,7 @@ class Question < ActiveRecord::Base
130
136
  has_reputation :total_votes,
131
137
  :source => :user,
132
138
  :aggregated_by => :sum,
133
- :source_of => {:reputation => :question_karma, :of => :author}
139
+ :source_of => { :reputation => :question_karma, :of => :author }
134
140
 
135
141
  has_reputation :difficulty,
136
142
  :source => :user,
@@ -143,10 +149,10 @@ class Answer < ActiveRecord::Base
143
149
 
144
150
  has_reputation :weighted_avg_rating,
145
151
  :source => [
146
- {:reputation => :avg_rating},
147
- {:reputation => :difficulty, :of => :question}],
152
+ { :reputation => :avg_rating },
153
+ { :reputation => :difficulty, :of => :question }],
148
154
  :aggregated_by => :product,
149
- :source_of => {:reputation => :answer_karma, :of => :author}
155
+ :source_of => { :reputation => :answer_karma, :of => :author }
150
156
 
151
157
  has_reputation :avg_rating,
152
158
  :source => :user,
@@ -163,15 +169,15 @@ class Phrase < ActiveRecord::Base
163
169
 
164
170
  has_reputation :maturity_all,
165
171
  :source => [
166
- {:reputation => :maturity, :of => :self, :scope => :ja},
167
- {:reputation => :maturity, :of => :self, :scope => :fr}],
172
+ { :reputation => :maturity, :of => :self, :scope => :ja },
173
+ { :reputation => :maturity, :of => :self, :scope => :fr }],
168
174
  :aggregated_by => :sum
169
175
 
170
176
  has_reputation :maturity,
171
177
  :source => { :reputation => :votes, :of => lambda {|this, s| this.translations.for(s)} },
172
178
  :aggregated_by => :sum,
173
179
  :scopes => [:ja, :fr, :de],
174
- :source_of => {:reputation => :maturity_all, :of => :self, :defined_for_scope => [:ja, :fr]}
180
+ :source_of => { :reputation => :maturity_all, :of => :self, :defined_for_scope => [:ja, :fr] }
175
181
 
176
182
  has_reputation :difficulty_with_scope,
177
183
  :source => :user,
@@ -186,5 +192,17 @@ class Translation < ActiveRecord::Base
186
192
  has_reputation :votes,
187
193
  :source => :user,
188
194
  :aggregated_by => :sum,
189
- :source_of => {:reputation => :maturity, :of => :phrase, :scope => :locale}
195
+ :source_of => { :reputation => :maturity, :of => :phrase, :scope => :locale}
196
+ end
197
+
198
+ class Person < ActiveRecord::Base
199
+ has_reputation :leadership,
200
+ :source => :person,
201
+ :aggregated_by => :sum
202
+ end
203
+
204
+ class Programmer < Person
205
+ end
206
+
207
+ class Designer < Person
190
208
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-reputation-system
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 4
8
+ - 5
9
9
  - 0
10
- version: 1.4.0
10
+ version: 1.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Katsuya Noguchi
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-09-10 00:00:00 Z
18
+ date: 2012-09-15 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  prerelease: false