activerecord-reputation-system 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +33 -0
- data/lib/generators/reputation_system/reputation_system_generator.rb +2 -0
- data/lib/generators/reputation_system/templates/add_data_to_evaluations.rb +9 -0
- data/lib/generators/reputation_system/templates/add_data_to_reputations.rb +9 -0
- data/lib/reputation_system.rb +1 -0
- data/lib/reputation_system/base.rb +2 -1
- data/lib/reputation_system/evaluation_methods.rb +1 -1
- data/lib/reputation_system/finder_methods.rb +6 -4
- data/lib/reputation_system/models/evaluation.rb +9 -7
- data/lib/reputation_system/models/reputation.rb +14 -8
- data/lib/reputation_system/models/reputation_message.rb +1 -1
- data/lib/reputation_system/reputation_methods.rb +3 -3
- data/lib/reputation_system/version.rb +1 -1
- data/spec/reputation_system/evaluation_methods_spec.rb +45 -45
- data/spec/reputation_system/finder_methods_spec.rb +1 -0
- data/spec/reputation_system/models/evaluation_spec.rb +8 -0
- data/spec/reputation_system/models/reputation_spec.rb +33 -2
- data/spec/reputation_system/reputation_methods_spec.rb +2 -2
- data/spec/spec_helper.rb +28 -1
- metadata +34 -32
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 357cba79dc17693f888aa559b94301e9cc6a0c39
|
4
|
+
data.tar.gz: 86542de25746208e733f163c661ec9b7be90ba2c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9656e9ca24b2a70661ef53336b6c96af676c1aa5d2d556267d223caf57aae0ff49fd79aa5e9feacda5ec0f16a1f2d80d7f1fc20d3c3e167023263e385c33d0c5
|
7
|
+
data.tar.gz: acc3482e4ea8e3d485d605fd711eecd7f7a70920049cb638472f4a532acb11f183dce97e374e32ec8e4e3c3c24e08c311c113648eb7f112543209ec210a00234
|
data/README.md
CHANGED
@@ -91,6 +91,38 @@ You can get target records that have been evaluated by a given source record:
|
|
91
91
|
Question.evaluated_by(:votes, @user) #=> [@question]
|
92
92
|
```
|
93
93
|
|
94
|
+
You can use a custom aggregation function, which is a feature available on this fork, but not on the original implementation.
|
95
|
+
You just need to provide the name of the method on the :aggregated_by option, and implement this method on the model.
|
96
|
+
On the example below, our aggregation function sums all values and multiply by ten:
|
97
|
+
```ruby
|
98
|
+
class Answer < ActiveRecord::Base
|
99
|
+
belongs_to :author, :class_name => 'User'
|
100
|
+
belongs_to :question
|
101
|
+
|
102
|
+
has_reputation :custom_rating,
|
103
|
+
:source => :user,
|
104
|
+
:aggregated_by => :custom_aggregation
|
105
|
+
|
106
|
+
def custom_aggregation(*args)
|
107
|
+
rep, source, weight = args[0..2]
|
108
|
+
|
109
|
+
# Ruby doesn't support method overloading, so let's handle parameters on a condition
|
110
|
+
|
111
|
+
# For a new source, these are the input parameters:
|
112
|
+
# rep, source, weight
|
113
|
+
if args.length === 3
|
114
|
+
rep.value + weight * source.value * 10
|
115
|
+
|
116
|
+
# For an updated source, these are the input parameters:
|
117
|
+
# rep, source, weight, oldValue, newSize
|
118
|
+
elsif args.length === 5
|
119
|
+
oldValue, newSize = args[3..4]
|
120
|
+
rep.value + (source.value - oldValue) * 10
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
94
126
|
## Documentation
|
95
127
|
|
96
128
|
Please refer [Wiki](https://github.com/twitter/activerecord-reputation-system/wiki) for available APIs and more information.
|
@@ -106,6 +138,7 @@ Katsuya Noguchi
|
|
106
138
|
1. [NARKOZ (Nihad Abbasov)](https://github.com/NARKOZ) - 4 commits
|
107
139
|
2. [elitheeli (Eli Fox-Epstein)](https://github.com/elitheeli) - 1 commit
|
108
140
|
3. [amrnt (Amr Tamimi)](https://github.com/amrnt) - 1 commit
|
141
|
+
4. [caiosba (Caio Almeida)](https://github.com/caiosba) - 1 commit
|
109
142
|
|
110
143
|
## Related Links
|
111
144
|
|
@@ -37,6 +37,8 @@ class ReputationSystemGenerator < Rails::Generators::Base
|
|
37
37
|
create_migration_file_if_not_exist 'change_evaluations_index_to_unique'
|
38
38
|
create_migration_file_if_not_exist 'change_reputation_messages_index_to_unique'
|
39
39
|
create_migration_file_if_not_exist 'change_reputations_index_to_unique'
|
40
|
+
create_migration_file_if_not_exist 'add_data_to_reputations'
|
41
|
+
create_migration_file_if_not_exist 'add_data_to_evaluations'
|
40
42
|
end
|
41
43
|
|
42
44
|
private
|
data/lib/reputation_system.rb
CHANGED
@@ -22,7 +22,8 @@ module ReputationSystem
|
|
22
22
|
|
23
23
|
def get_attributes_of(reputation)
|
24
24
|
of = reputation[:of]
|
25
|
-
attrs =
|
25
|
+
attrs = (of == :self) ? self : self.instance_eval(of.to_s) if of.is_a?(String) || of.is_a?(Symbol)
|
26
|
+
attrs = attrs.to_a if attrs.is_a?(ActiveRecord::Associations::CollectionProxy)
|
26
27
|
attrs = self.instance_exec(self, &of) if of.is_a?(Proc)
|
27
28
|
attrs = [attrs] unless attrs.is_a? Array
|
28
29
|
attrs.compact
|
@@ -25,7 +25,7 @@ module ReputationSystem
|
|
25
25
|
options[:select] ||= sanitize_sql_array(["%s.*", self.table_name])
|
26
26
|
options[:joins] = sanitize_sql_array(["JOIN rs_evaluations ON %s.id = rs_evaluations.target_id AND rs_evaluations.target_type = ? AND rs_evaluations.reputation_name = ? AND rs_evaluations.source_id = ? AND rs_evaluations.source_type = ?", self.name, srn.to_s, source.id, source_type])
|
27
27
|
options[:joins] = sanitize_sql_array([options[:joins], self.table_name])
|
28
|
-
|
28
|
+
joins(options[:joins]).select(options[:select])
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -27,7 +27,7 @@ module FinderMethods
|
|
27
27
|
options[:select] = build_select_statement(table_name, reputation_name, options[:select])
|
28
28
|
options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
|
29
29
|
options[:conditions] = build_condition_statement(reputation_name, options[:conditions])
|
30
|
-
|
30
|
+
joins(options[:joins]).select(options[:select]).where(options[:conditions]).send(find_scope)
|
31
31
|
end
|
32
32
|
|
33
33
|
def count_with_reputation(*args)
|
@@ -35,7 +35,7 @@ module FinderMethods
|
|
35
35
|
options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
|
36
36
|
options[:conditions] = build_condition_statement(reputation_name, options[:conditions])
|
37
37
|
options[:conditions][0].gsub!(reputation_name.to_s, "COALESCE(rs_reputations.value, 0)")
|
38
|
-
|
38
|
+
joins(options[:joins]).select(options[:select]).where(options[:conditions]).send(find_scope).count
|
39
39
|
end
|
40
40
|
|
41
41
|
def find_with_normalized_reputation(*args)
|
@@ -43,7 +43,7 @@ module FinderMethods
|
|
43
43
|
options[:select] = build_select_statement(table_name, reputation_name, options[:select], srn, true)
|
44
44
|
options[:joins] = build_join_statement(table_name, name, srn, options[:joins])
|
45
45
|
options[:conditions] = build_condition_statement(reputation_name, options[:conditions], srn, true)
|
46
|
-
|
46
|
+
joins(options[:joins]).select(options[:select]).where(options[:conditions]).send(find_scope)
|
47
47
|
end
|
48
48
|
|
49
49
|
def find_with_reputation_sql(*args)
|
@@ -53,8 +53,10 @@ module FinderMethods
|
|
53
53
|
options[:conditions] = build_condition_statement(reputation_name, options[:conditions])
|
54
54
|
if respond_to?(:construct_finder_sql, true)
|
55
55
|
construct_finder_sql(options)
|
56
|
-
|
56
|
+
elsif respond_to?(:construct_finder_arel, true)
|
57
57
|
construct_finder_arel(options).to_sql
|
58
|
+
else
|
59
|
+
joins(options[:joins]).select(options[:select]).where(options[:conditions]).send(find_scope).to_sql
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -31,15 +31,17 @@ module ReputationSystem
|
|
31
31
|
validates_uniqueness_of :source_id, :scope => [:reputation_name, :source_type, :target_id, :target_type]
|
32
32
|
validate :source_must_be_defined_for_reputation_in_network
|
33
33
|
|
34
|
+
serialize :data, Hash
|
35
|
+
|
34
36
|
def self.find_by_reputation_name_and_source_and_target(reputation_name, source, target)
|
35
37
|
source_type = get_source_type_for_sti(source.class.name, target.class.name, reputation_name)
|
36
|
-
ReputationSystem::Evaluation.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
ReputationSystem::Evaluation.where(
|
39
|
+
:reputation_name => reputation_name.to_s,
|
40
|
+
:source_id => source.id,
|
41
|
+
:source_type => source_type,
|
42
|
+
:target_id => target.id,
|
43
|
+
:target_type => target.class.name
|
44
|
+
).first
|
43
45
|
end
|
44
46
|
|
45
47
|
def self.create_evaluation(reputation_name, value, source, target)
|
@@ -31,10 +31,10 @@ module ReputationSystem
|
|
31
31
|
before_validation :set_target_type_for_sti
|
32
32
|
before_save :change_zero_value_in_case_of_product_process
|
33
33
|
|
34
|
-
VALID_PROCESSES = ['sum', 'average', 'product']
|
35
|
-
validates_inclusion_of :aggregated_by, :in => VALID_PROCESSES, :message => "Value chosen for aggregated_by is not valid process"
|
36
34
|
validates_uniqueness_of :reputation_name, :scope => [:target_id, :target_type]
|
37
35
|
|
36
|
+
serialize :data, Hash
|
37
|
+
|
38
38
|
def self.find_by_reputation_name_and_target(reputation_name, target)
|
39
39
|
target_type = get_target_type_for_sti(target, reputation_name)
|
40
40
|
ReputationSystem::Reputation.find_by_reputation_name_and_target_id_and_target_type(reputation_name.to_s, target.id, target_type)
|
@@ -66,7 +66,11 @@ module ReputationSystem
|
|
66
66
|
when :product
|
67
67
|
rep.value *= (newValue * weight)
|
68
68
|
else
|
69
|
-
|
69
|
+
if source.target.respond_to?(process)
|
70
|
+
rep.value = source.target.send(process, rep, source, weight)
|
71
|
+
else
|
72
|
+
raise ArgumentError, "#{process} process is not supported yet"
|
73
|
+
end
|
70
74
|
end
|
71
75
|
save_succeeded = rep.save
|
72
76
|
ReputationSystem::ReputationMessage.add_reputation_message_if_not_exist(source, rep)
|
@@ -90,7 +94,11 @@ module ReputationSystem
|
|
90
94
|
when :product
|
91
95
|
rep.value = (rep.value * newValue) / oldValue
|
92
96
|
else
|
93
|
-
|
97
|
+
if source.target.respond_to?(process)
|
98
|
+
rep.value = source.target.send(process, rep, source, weight, oldValue, newSize)
|
99
|
+
else
|
100
|
+
raise ArgumentError, "#{process} process is not supported yet"
|
101
|
+
end
|
94
102
|
end
|
95
103
|
end
|
96
104
|
save_succeeded = rep.save
|
@@ -175,13 +183,11 @@ module ReputationSystem
|
|
175
183
|
end
|
176
184
|
|
177
185
|
def self.max(reputation_name, target_type)
|
178
|
-
ReputationSystem::Reputation.maximum(:value
|
179
|
-
:conditions => {:reputation_name => reputation_name.to_s, :target_type => target_type, :active => true})
|
186
|
+
ReputationSystem::Reputation.where(:reputation_name => reputation_name.to_s, :target_type => target_type, :active => true).maximum(:value)
|
180
187
|
end
|
181
188
|
|
182
189
|
def self.min(reputation_name, target_type)
|
183
|
-
ReputationSystem::Reputation.minimum(:value
|
184
|
-
:conditions => {:reputation_name => reputation_name.to_s, :target_type => target_type, :active => true})
|
190
|
+
ReputationSystem::Reputation.where(:reputation_name => reputation_name.to_s, :target_type => target_type, :active => true).minimum(:value)
|
185
191
|
end
|
186
192
|
|
187
193
|
def self.get_target_type_for_sti(target, reputation_name)
|
@@ -25,21 +25,21 @@ module ReputationSystem
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def activate_all_reputations
|
28
|
-
ReputationSystem::Reputation.
|
28
|
+
ReputationSystem::Reputation.where(:target_id => self.id, :target_type => self.class.name, :active => false).each do |r|
|
29
29
|
r.active = true
|
30
30
|
r.save!
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
def deactivate_all_reputations
|
35
|
-
ReputationSystem::Reputation.
|
35
|
+
ReputationSystem::Reputation.where(:target_id => self.id, :target_type => self.class.name, :active => true).each do |r|
|
36
36
|
r.active = false
|
37
37
|
r.save!
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def reputations_activated?(reputation_name)
|
42
|
-
r = ReputationSystem::Reputation.
|
42
|
+
r = ReputationSystem::Reputation.where(:reputation_name => reputation_name.to_s, :target_id => self.id, :target_type => self.class.name).first
|
43
43
|
r ? r.active : false
|
44
44
|
end
|
45
45
|
|
@@ -30,20 +30,20 @@ describe ReputationSystem::EvaluationMethods do
|
|
30
30
|
it "should return false if it has not already been evaluated by a given source" do
|
31
31
|
user = User.create! :name => 'katsuya'
|
32
32
|
@question.add_evaluation(:total_votes, 3, user)
|
33
|
-
@question.has_evaluation?(:total_votes, @user).should
|
33
|
+
@question.has_evaluation?(:total_votes, @user).should be false
|
34
34
|
end
|
35
35
|
it "should return true if it has been evaluated by a given source" do
|
36
36
|
@question.add_evaluation(:total_votes, 3, @user)
|
37
|
-
@question.has_evaluation?(:total_votes, @user).should
|
37
|
+
@question.has_evaluation?(:total_votes, @user).should be true
|
38
38
|
end
|
39
39
|
context "With Scopes" do
|
40
40
|
it "should return false if it has not already been evaluated by a given source" do
|
41
41
|
@phrase.add_evaluation(:difficulty_with_scope, 3, @user, :s1)
|
42
|
-
@phrase.has_evaluation?(:difficulty_with_scope, @user, :s2).should
|
42
|
+
@phrase.has_evaluation?(:difficulty_with_scope, @user, :s2).should be false
|
43
43
|
end
|
44
44
|
it "should return true if it has been evaluated by a given source" do
|
45
45
|
@phrase.add_evaluation(:difficulty_with_scope, 3, @user, :s1)
|
46
|
-
@phrase.has_evaluation?(:difficulty_with_scope, @user, :s1).should
|
46
|
+
@phrase.has_evaluation?(:difficulty_with_scope, @user, :s1).should be true
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -57,9 +57,9 @@ describe ReputationSystem::EvaluationMethods do
|
|
57
57
|
user2 = User.create!(:name => 'katsuya')
|
58
58
|
question2 = Question.create!(:text => 'Question 2', :author_id => @user.id)
|
59
59
|
question3 = Question.create!(:text => 'Question 3', :author_id => @user.id)
|
60
|
-
@question.add_evaluation(:total_votes, 1, @user).should
|
61
|
-
question2.add_evaluation(:total_votes, 2, user2).should
|
62
|
-
question3.add_evaluation(:total_votes, 3, @user).should
|
60
|
+
@question.add_evaluation(:total_votes, 1, @user).should be true
|
61
|
+
question2.add_evaluation(:total_votes, 2, user2).should be true
|
62
|
+
question3.add_evaluation(:total_votes, 3, @user).should be true
|
63
63
|
Question.evaluated_by(:total_votes, @user).should == [@question, question3]
|
64
64
|
Question.evaluated_by(:total_votes, user2).should == [question2]
|
65
65
|
end
|
@@ -68,14 +68,14 @@ describe ReputationSystem::EvaluationMethods do
|
|
68
68
|
it "should return an array of targets evaluated by a given source on appropriate scope" do
|
69
69
|
user2 = User.create!(:name => 'katsuya')
|
70
70
|
phrase2 = Phrase.create!(:text => "Two")
|
71
|
-
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should
|
72
|
-
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
73
|
-
@phrase.add_evaluation(:difficulty_with_scope, 3, user2, :s2).should
|
74
|
-
@phrase.add_evaluation(:difficulty_with_scope, 4, user2, :s3).should
|
75
|
-
phrase2.add_evaluation(:difficulty_with_scope, 1, user2, :s1).should
|
76
|
-
phrase2.add_evaluation(:difficulty_with_scope, 2, user2, :s2).should
|
77
|
-
phrase2.add_evaluation(:difficulty_with_scope, 3, @user, :s2).should
|
78
|
-
phrase2.add_evaluation(:difficulty_with_scope, 4, @user, :s3).should
|
71
|
+
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be true
|
72
|
+
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
73
|
+
@phrase.add_evaluation(:difficulty_with_scope, 3, user2, :s2).should be true
|
74
|
+
@phrase.add_evaluation(:difficulty_with_scope, 4, user2, :s3).should be true
|
75
|
+
phrase2.add_evaluation(:difficulty_with_scope, 1, user2, :s1).should be true
|
76
|
+
phrase2.add_evaluation(:difficulty_with_scope, 2, user2, :s2).should be true
|
77
|
+
phrase2.add_evaluation(:difficulty_with_scope, 3, @user, :s2).should be true
|
78
|
+
phrase2.add_evaluation(:difficulty_with_scope, 4, @user, :s3).should be true
|
79
79
|
Phrase.evaluated_by(:difficulty_with_scope, @user, :s1).should == [@phrase]
|
80
80
|
Phrase.evaluated_by(:difficulty_with_scope, user2, :s1).should == [phrase2]
|
81
81
|
Phrase.evaluated_by(:difficulty_with_scope, @user, :s2).should == [@phrase, phrase2]
|
@@ -94,9 +94,9 @@ describe ReputationSystem::EvaluationMethods do
|
|
94
94
|
it "should return an array of sources evaluated the target" do
|
95
95
|
user2 = User.create!(:name => 'katsuya')
|
96
96
|
question2 = Question.create!(:text => 'Question 2', :author_id => @user.id)
|
97
|
-
@question.add_evaluation(:total_votes, 1, @user).should
|
98
|
-
question2.add_evaluation(:total_votes, 1, @user).should
|
99
|
-
question2.add_evaluation(:total_votes, 2, user2).should
|
97
|
+
@question.add_evaluation(:total_votes, 1, @user).should be true
|
98
|
+
question2.add_evaluation(:total_votes, 1, @user).should be true
|
99
|
+
question2.add_evaluation(:total_votes, 2, user2).should be true
|
100
100
|
@question.evaluators_for(:total_votes).should == [@user]
|
101
101
|
question2.evaluators_for(:total_votes).should == [@user, user2]
|
102
102
|
end
|
@@ -104,10 +104,10 @@ describe ReputationSystem::EvaluationMethods do
|
|
104
104
|
context "With Scopes" do
|
105
105
|
it "should return an array of targets evaluated by a given source on appropriate scope" do
|
106
106
|
user2 = User.create!(:name => 'katsuya')
|
107
|
-
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should
|
108
|
-
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
109
|
-
@phrase.add_evaluation(:difficulty_with_scope, 3, user2, :s2).should
|
110
|
-
@phrase.add_evaluation(:difficulty_with_scope, 4, user2, :s3).should
|
107
|
+
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be true
|
108
|
+
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
109
|
+
@phrase.add_evaluation(:difficulty_with_scope, 3, user2, :s2).should be true
|
110
|
+
@phrase.add_evaluation(:difficulty_with_scope, 4, user2, :s3).should be true
|
111
111
|
@phrase.evaluators_for(:difficulty_with_scope, :s1).should == [@user]
|
112
112
|
@phrase.evaluators_for(:difficulty_with_scope, :s2).should == [@user, user2]
|
113
113
|
@phrase.evaluators_for(:difficulty_with_scope, :s3).should == [user2]
|
@@ -117,7 +117,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
117
117
|
|
118
118
|
describe "#add_evaluation" do
|
119
119
|
it "should create evaluation in case of valid input" do
|
120
|
-
@question.add_evaluation(:total_votes, 1, @user).should
|
120
|
+
@question.add_evaluation(:total_votes, 1, @user).should be true
|
121
121
|
@question.reputation_for(:total_votes).should == 1
|
122
122
|
end
|
123
123
|
|
@@ -142,8 +142,8 @@ describe ReputationSystem::EvaluationMethods do
|
|
142
142
|
|
143
143
|
context "with scopes" do
|
144
144
|
it "should add evaluation on appropriate scope" do
|
145
|
-
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should
|
146
|
-
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
145
|
+
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be true
|
146
|
+
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
147
147
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 1
|
148
148
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 2
|
149
149
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -161,30 +161,30 @@ describe ReputationSystem::EvaluationMethods do
|
|
161
161
|
|
162
162
|
describe "#add_or_update_evaluation" do
|
163
163
|
it "should create evaluation if it does not exist" do
|
164
|
-
@question.add_or_update_evaluation(:total_votes, 1, @user).should
|
164
|
+
@question.add_or_update_evaluation(:total_votes, 1, @user).should be true
|
165
165
|
@question.reputation_for(:total_votes).should == 1
|
166
166
|
end
|
167
167
|
|
168
168
|
it "should update evaluation if it exists already" do
|
169
169
|
@question.add_evaluation(:total_votes, 1, @user)
|
170
|
-
@question.add_or_update_evaluation(:total_votes, 2, @user).should
|
170
|
+
@question.add_or_update_evaluation(:total_votes, 2, @user).should be true
|
171
171
|
@question.reputation_for(:total_votes).should == 2
|
172
172
|
end
|
173
173
|
|
174
174
|
context "with scopes" do
|
175
175
|
it "should add evaluation on appropriate scope if it does not exist" do
|
176
|
-
@phrase.add_or_update_evaluation(:difficulty_with_scope, 1, @user, :s1).should
|
177
|
-
@phrase.add_or_update_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
176
|
+
@phrase.add_or_update_evaluation(:difficulty_with_scope, 1, @user, :s1).should be true
|
177
|
+
@phrase.add_or_update_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
178
178
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 1
|
179
179
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 2
|
180
180
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
181
181
|
end
|
182
182
|
|
183
183
|
it "should update evaluation on appropriate scope if it exists already" do
|
184
|
-
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should
|
185
|
-
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
186
|
-
@phrase.add_or_update_evaluation(:difficulty_with_scope, 3, @user, :s1).should
|
187
|
-
@phrase.add_or_update_evaluation(:difficulty_with_scope, 5, @user, :s2).should
|
184
|
+
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be true
|
185
|
+
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
186
|
+
@phrase.add_or_update_evaluation(:difficulty_with_scope, 3, @user, :s1).should be true
|
187
|
+
@phrase.add_or_update_evaluation(:difficulty_with_scope, 5, @user, :s2).should be true
|
188
188
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 3
|
189
189
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 5
|
190
190
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -208,7 +208,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
208
208
|
end
|
209
209
|
|
210
210
|
it "should update evaluation in case of valid input" do
|
211
|
-
@question.update_evaluation(:total_votes, 2, @user).should
|
211
|
+
@question.update_evaluation(:total_votes, 2, @user).should be true
|
212
212
|
@question.reputation_for(:total_votes).should == 2
|
213
213
|
end
|
214
214
|
|
@@ -226,11 +226,11 @@ describe ReputationSystem::EvaluationMethods do
|
|
226
226
|
|
227
227
|
context "With Scopes" do
|
228
228
|
before :each do
|
229
|
-
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should
|
229
|
+
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be true
|
230
230
|
end
|
231
231
|
|
232
232
|
it "should update evaluation on appropriate scope" do
|
233
|
-
@phrase.update_evaluation(:difficulty_with_scope, 5, @user, :s2).should
|
233
|
+
@phrase.update_evaluation(:difficulty_with_scope, 5, @user, :s2).should be true
|
234
234
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
|
235
235
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 5
|
236
236
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -296,7 +296,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
296
296
|
end
|
297
297
|
|
298
298
|
it "should delete evaluation in case of valid input" do
|
299
|
-
@question.delete_evaluation(:total_votes, @user).should
|
299
|
+
@question.delete_evaluation(:total_votes, @user).should be true
|
300
300
|
@question.reputation_for(:total_votes).should == 0
|
301
301
|
end
|
302
302
|
|
@@ -305,7 +305,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
305
305
|
end
|
306
306
|
|
307
307
|
it "should return false if evaluation does not exist" do
|
308
|
-
@answer.delete_evaluation(:avg_rating, @user).should
|
308
|
+
@answer.delete_evaluation(:avg_rating, @user).should be false
|
309
309
|
end
|
310
310
|
|
311
311
|
context "With Scopes" do
|
@@ -314,7 +314,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
314
314
|
end
|
315
315
|
|
316
316
|
it "should delete evaluation on appropriate scope" do
|
317
|
-
@phrase.delete_evaluation(:difficulty_with_scope, @user, :s2).should
|
317
|
+
@phrase.delete_evaluation(:difficulty_with_scope, @user, :s2).should be true
|
318
318
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
|
319
319
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 0
|
320
320
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -332,13 +332,13 @@ describe ReputationSystem::EvaluationMethods do
|
|
332
332
|
|
333
333
|
describe "#increase_evaluation" do
|
334
334
|
it "should add evaluation if it does not exist" do
|
335
|
-
@question.increase_evaluation(:total_votes, 2, @user).should
|
335
|
+
@question.increase_evaluation(:total_votes, 2, @user).should be true
|
336
336
|
@question.reputation_for(:total_votes).should == 2
|
337
337
|
end
|
338
338
|
|
339
339
|
it "should increase evaluation if it exists already" do
|
340
340
|
@question.add_evaluation(:total_votes, 1, @user)
|
341
|
-
@question.increase_evaluation(:total_votes, 2, @user).should
|
341
|
+
@question.increase_evaluation(:total_votes, 2, @user).should be true
|
342
342
|
@question.reputation_for(:total_votes).should == 3
|
343
343
|
end
|
344
344
|
|
@@ -348,7 +348,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
348
348
|
end
|
349
349
|
|
350
350
|
it "should increase evaluation on appropriate scope" do
|
351
|
-
@phrase.increase_evaluation(:difficulty_with_scope, 5, @user, :s2).should
|
351
|
+
@phrase.increase_evaluation(:difficulty_with_scope, 5, @user, :s2).should be true
|
352
352
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
|
353
353
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == 7
|
354
354
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -358,13 +358,13 @@ describe ReputationSystem::EvaluationMethods do
|
|
358
358
|
|
359
359
|
describe "#decrease_evaluation" do
|
360
360
|
it "should add evaluation if it does not exist" do
|
361
|
-
@question.decrease_evaluation(:total_votes, 2, @user).should
|
361
|
+
@question.decrease_evaluation(:total_votes, 2, @user).should be true
|
362
362
|
@question.reputation_for(:total_votes).should == -2
|
363
363
|
end
|
364
364
|
|
365
365
|
it "should increase evaluation if it exists already" do
|
366
366
|
@question.add_evaluation(:total_votes, 1, @user)
|
367
|
-
@question.decrease_evaluation(:total_votes, 2, @user).should
|
367
|
+
@question.decrease_evaluation(:total_votes, 2, @user).should be true
|
368
368
|
@question.reputation_for(:total_votes).should == -1
|
369
369
|
end
|
370
370
|
|
@@ -374,7 +374,7 @@ describe ReputationSystem::EvaluationMethods do
|
|
374
374
|
end
|
375
375
|
|
376
376
|
it "should decrease evaluation on appropriate scope" do
|
377
|
-
@phrase.decrease_evaluation(:difficulty_with_scope, 5, @user, :s2).should
|
377
|
+
@phrase.decrease_evaluation(:difficulty_with_scope, 5, @user, :s2).should be true
|
378
378
|
@phrase.reputation_for(:difficulty_with_scope, :s1).should == 0
|
379
379
|
@phrase.reputation_for(:difficulty_with_scope, :s2).should == -3
|
380
380
|
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
|
@@ -177,6 +177,7 @@ describe ReputationSystem::FinderMethods do
|
|
177
177
|
"FROM \"questions\" JOIN users ON questions.author_id = users.id "\
|
178
178
|
"LEFT JOIN rs_reputations ON questions.id = rs_reputations.target_id AND rs_reputations.target_type = 'Question' AND rs_reputations.reputation_name = 'total_votes' AND rs_reputations.active = 't' "\
|
179
179
|
"WHERE (COALESCE(rs_reputations.value, 0) > 0.6) "\
|
180
|
+
" " if ActiveRecord::VERSION::STRING >= '4' \
|
180
181
|
"ORDER BY total_votes"
|
181
182
|
end
|
182
183
|
end
|
@@ -59,4 +59,12 @@ describe ReputationSystem::Evaluation do
|
|
59
59
|
ReputationSystem::ReputationMessage.find_by_sender_id_and_sender_type(evaluation.id, evaluation.class.name).should be_nil
|
60
60
|
end
|
61
61
|
end
|
62
|
+
|
63
|
+
context "Additional Data" do
|
64
|
+
it "should have data as a serialized field" do
|
65
|
+
@attributes = {:reputation_name => 'total_votes', :source => @user, :target => @question, :value => 1}
|
66
|
+
e = ReputationSystem::Evaluation.create!(@attributes)
|
67
|
+
e.data.should be_a(Hash)
|
68
|
+
end
|
69
|
+
end
|
62
70
|
end
|
@@ -46,8 +46,12 @@ describe ReputationSystem::Reputation do
|
|
46
46
|
ReputationSystem::Reputation.create(:reputation_name => "karma3", :target_id => @user.id, :target_type => @user.class.to_s, :aggregated_by => 'product').should be_valid
|
47
47
|
end
|
48
48
|
|
49
|
-
it "should
|
50
|
-
ReputationSystem::Reputation.create(:reputation_name => "karma", :target_id => @user.id, :target_type => @user.class.to_s, :aggregated_by => '
|
49
|
+
it "should be able to create reputation with custom process" do
|
50
|
+
ReputationSystem::Reputation.create(:reputation_name => "karma", :target_id => @user.id, :target_type => @user.class.to_s, :aggregated_by => 'custom_process').should be_valid
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to create reputation with custom process from source" do
|
54
|
+
ReputationSystem::Reputation.create(:reputation_name => "custom_rating", :target_id => @user.id, :target_type => @user.class.to_s, :aggregated_by => 'custom_rating').should be_valid
|
51
55
|
end
|
52
56
|
|
53
57
|
it "should not be able to create reputation of the same name for the same target" do
|
@@ -133,4 +137,31 @@ describe ReputationSystem::Reputation do
|
|
133
137
|
answer.reputation_for(:avg_rating).should be_within(DELTA).of(3)
|
134
138
|
end
|
135
139
|
end
|
140
|
+
|
141
|
+
describe "custom aggregation function" do
|
142
|
+
it "should calculate based on a custom function for new source" do
|
143
|
+
user1 = User.create! :name => 'dick'
|
144
|
+
user2 = User.create! :name => 'katsuya'
|
145
|
+
answer = Answer.create!
|
146
|
+
answer.add_or_update_evaluation(:custom_rating, 3, user1)
|
147
|
+
answer.add_or_update_evaluation(:custom_rating, 2, user2)
|
148
|
+
answer.reputation_for(:custom_rating).should be_within(DELTA).of(50)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should calculate based on a custom function for updated source" do
|
152
|
+
user1 = User.create! :name => 'dick'
|
153
|
+
user2 = User.create! :name => 'katsuya'
|
154
|
+
answer = Answer.create!
|
155
|
+
answer.add_or_update_evaluation(:custom_rating, 3, user1)
|
156
|
+
answer.add_or_update_evaluation(:custom_rating, 2, user1)
|
157
|
+
answer.reputation_for(:custom_rating).should be_within(DELTA).of(20)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "additional data" do
|
162
|
+
it "should have data as a serialized field" do
|
163
|
+
r = ReputationSystem::Reputation.create!(:reputation_name => "karma", :target_id => @user.id, :target_type => @user.class.to_s, :aggregated_by => 'sum')
|
164
|
+
r.data.should be_a(Hash)
|
165
|
+
end
|
166
|
+
end
|
136
167
|
end
|
@@ -153,9 +153,9 @@ describe ReputationSystem::ReputationMethods do
|
|
153
153
|
@question2.add_evaluation(:total_votes, 70, @user)
|
154
154
|
@question.add_evaluation(:total_votes, 100, @user)
|
155
155
|
@question.deactivate_all_reputations
|
156
|
-
ReputationSystem::Reputation.
|
156
|
+
ReputationSystem::Reputation.where(:reputation_name => 'total_votes', :active => true).maximum(:value).should == 70
|
157
157
|
@question.activate_all_reputations
|
158
|
-
ReputationSystem::Reputation.
|
158
|
+
ReputationSystem::Reputation.where(:reputation_name => 'total_votes', :active => true).maximum(:value).should == 100
|
159
159
|
end
|
160
160
|
end
|
161
161
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -43,6 +43,7 @@ ActiveRecord::Schema.define do
|
|
43
43
|
t.references :source, :polymorphic => true
|
44
44
|
t.references :target, :polymorphic => true
|
45
45
|
t.float :value, :default => 0
|
46
|
+
t.text :data
|
46
47
|
t.timestamps
|
47
48
|
end
|
48
49
|
|
@@ -56,6 +57,7 @@ ActiveRecord::Schema.define do
|
|
56
57
|
t.string :aggregated_by
|
57
58
|
t.references :target, :polymorphic => true
|
58
59
|
t.boolean :active, :default => true
|
60
|
+
t.text :data
|
59
61
|
t.timestamps
|
60
62
|
end
|
61
63
|
|
@@ -132,6 +134,14 @@ class User < ActiveRecord::Base
|
|
132
134
|
has_reputation :answer_karma,
|
133
135
|
:source => { :reputation => :weighted_avg_rating, :of => :answers },
|
134
136
|
:aggregated_by => :average
|
137
|
+
|
138
|
+
has_reputation :custom_rating,
|
139
|
+
:source => { :reputation => :custom_rating, :of => :answers },
|
140
|
+
:aggregated_by => :custom_rating
|
141
|
+
|
142
|
+
def custom_process
|
143
|
+
123
|
144
|
+
end
|
135
145
|
end
|
136
146
|
|
137
147
|
class Question < ActiveRecord::Base
|
@@ -161,12 +171,29 @@ class Answer < ActiveRecord::Base
|
|
161
171
|
has_reputation :avg_rating,
|
162
172
|
:source => :user,
|
163
173
|
:aggregated_by => :average
|
174
|
+
|
175
|
+
has_reputation :custom_rating,
|
176
|
+
:source => :user,
|
177
|
+
:aggregated_by => :custom_aggregation,
|
178
|
+
:source_of => { :reputation => :custom_rating, :of => :author }
|
179
|
+
|
180
|
+
def custom_aggregation(*args)
|
181
|
+
rep, source, weight = args[0..2]
|
182
|
+
# rep, source, weight
|
183
|
+
if args.length === 3
|
184
|
+
rep.value + weight * source.value * 10
|
185
|
+
# rep, source, weight, oldValue, newSize
|
186
|
+
elsif args.length === 5
|
187
|
+
oldValue, newSize = args[3..4]
|
188
|
+
rep.value + (source.value - oldValue) * 10
|
189
|
+
end
|
190
|
+
end
|
164
191
|
end
|
165
192
|
|
166
193
|
class Phrase < ActiveRecord::Base
|
167
194
|
has_many :translations do
|
168
195
|
def for(locale)
|
169
|
-
self.
|
196
|
+
self.where(:locale => locale.to_s).to_a
|
170
197
|
end
|
171
198
|
end
|
172
199
|
|
metadata
CHANGED
@@ -1,52 +1,60 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-reputation-system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 3.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Katsuya Noguchi
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-10-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
14
|
+
name: protected_attributes
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
|
-
type: :
|
20
|
+
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
30
41
|
- !ruby/object:Gem::Dependency
|
31
42
|
name: rake
|
32
43
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
44
|
requirements:
|
35
|
-
- -
|
45
|
+
- - '>='
|
36
46
|
- !ruby/object:Gem::Version
|
37
47
|
version: 0.8.7
|
38
48
|
type: :development
|
39
49
|
prerelease: false
|
40
50
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
51
|
requirements:
|
43
|
-
- -
|
52
|
+
- - '>='
|
44
53
|
- !ruby/object:Gem::Version
|
45
54
|
version: 0.8.7
|
46
55
|
- !ruby/object:Gem::Dependency
|
47
56
|
name: rspec
|
48
57
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
58
|
requirements:
|
51
59
|
- - ~>
|
52
60
|
- !ruby/object:Gem::Version
|
@@ -54,7 +62,6 @@ dependencies:
|
|
54
62
|
type: :development
|
55
63
|
prerelease: false
|
56
64
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
65
|
requirements:
|
59
66
|
- - ~>
|
60
67
|
- !ruby/object:Gem::Version
|
@@ -62,39 +69,34 @@ dependencies:
|
|
62
69
|
- !ruby/object:Gem::Dependency
|
63
70
|
name: rdoc
|
64
71
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
72
|
requirements:
|
67
|
-
- -
|
73
|
+
- - '>='
|
68
74
|
- !ruby/object:Gem::Version
|
69
75
|
version: '0'
|
70
76
|
type: :development
|
71
77
|
prerelease: false
|
72
78
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
79
|
requirements:
|
75
|
-
- -
|
80
|
+
- - '>='
|
76
81
|
- !ruby/object:Gem::Version
|
77
82
|
version: '0'
|
78
83
|
- !ruby/object:Gem::Dependency
|
79
84
|
name: database_cleaner
|
80
85
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
86
|
requirements:
|
83
87
|
- - ~>
|
84
88
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
89
|
+
version: 1.2.0
|
86
90
|
type: :development
|
87
91
|
prerelease: false
|
88
92
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
93
|
requirements:
|
91
94
|
- - ~>
|
92
95
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
96
|
+
version: 1.2.0
|
94
97
|
- !ruby/object:Gem::Dependency
|
95
98
|
name: sqlite3
|
96
99
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
100
|
requirements:
|
99
101
|
- - ~>
|
100
102
|
- !ruby/object:Gem::Version
|
@@ -102,7 +104,6 @@ dependencies:
|
|
102
104
|
type: :development
|
103
105
|
prerelease: false
|
104
106
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
107
|
requirements:
|
107
108
|
- - ~>
|
108
109
|
- !ruby/object:Gem::Version
|
@@ -120,6 +121,8 @@ files:
|
|
120
121
|
- Rakefile
|
121
122
|
- lib/activerecord-reputation-system.rb
|
122
123
|
- lib/generators/reputation_system/reputation_system_generator.rb
|
124
|
+
- lib/generators/reputation_system/templates/add_data_to_evaluations.rb
|
125
|
+
- lib/generators/reputation_system/templates/add_data_to_reputations.rb
|
123
126
|
- lib/generators/reputation_system/templates/add_evaluations_index.rb
|
124
127
|
- lib/generators/reputation_system/templates/add_reputation_messages_index.rb
|
125
128
|
- lib/generators/reputation_system/templates/add_reputations_index.rb
|
@@ -127,6 +130,7 @@ files:
|
|
127
130
|
- lib/generators/reputation_system/templates/change_reputation_messages_index_to_unique.rb
|
128
131
|
- lib/generators/reputation_system/templates/change_reputations_index_to_unique.rb
|
129
132
|
- lib/generators/reputation_system/templates/create_reputation_system.rb
|
133
|
+
- lib/reputation_system.rb
|
130
134
|
- lib/reputation_system/base.rb
|
131
135
|
- lib/reputation_system/evaluation_methods.rb
|
132
136
|
- lib/reputation_system/finder_methods.rb
|
@@ -139,7 +143,6 @@ files:
|
|
139
143
|
- lib/reputation_system/reputation_methods.rb
|
140
144
|
- lib/reputation_system/scope_methods.rb
|
141
145
|
- lib/reputation_system/version.rb
|
142
|
-
- lib/reputation_system.rb
|
143
146
|
- spec/reputation_system/base_spec.rb
|
144
147
|
- spec/reputation_system/evaluation_methods_spec.rb
|
145
148
|
- spec/reputation_system/finder_methods_spec.rb
|
@@ -152,27 +155,26 @@ files:
|
|
152
155
|
- spec/spec_helper.rb
|
153
156
|
homepage: https://github.com/twitter/activerecord-reputation-system
|
154
157
|
licenses: []
|
158
|
+
metadata: {}
|
155
159
|
post_install_message:
|
156
160
|
rdoc_options: []
|
157
161
|
require_paths:
|
158
162
|
- lib
|
159
163
|
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
-
none: false
|
161
164
|
requirements:
|
162
|
-
- -
|
165
|
+
- - '>='
|
163
166
|
- !ruby/object:Gem::Version
|
164
167
|
version: '0'
|
165
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
-
none: false
|
167
169
|
requirements:
|
168
|
-
- -
|
170
|
+
- - '>='
|
169
171
|
- !ruby/object:Gem::Version
|
170
172
|
version: '0'
|
171
173
|
requirements: []
|
172
174
|
rubyforge_project:
|
173
|
-
rubygems_version:
|
175
|
+
rubygems_version: 2.2.2
|
174
176
|
signing_key:
|
175
|
-
specification_version:
|
177
|
+
specification_version: 4
|
176
178
|
summary: ActiveRecord Reputation System gem allows rails apps to compute and publish
|
177
179
|
reputation scores for active record models
|
178
180
|
test_files: []
|