activerecord-reputation-system 2.0.2 → 3.0.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.
- 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: []
|