activerecord-reputation-system 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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