Skip to content
This repository has been archived by the owner on Nov 13, 2021. It is now read-only.

Commit

Permalink
Refactor codes by removing duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
Katsuya Noguchi committed Jul 15, 2012
1 parent f0ed802 commit 373e665
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 150 deletions.
3 changes: 1 addition & 2 deletions lib/reputation_system.rb
Expand Up @@ -16,7 +16,6 @@

require 'reputation_system/base'
require 'reputation_system/query'
require 'reputation_system/normalization'
require 'reputation_system/evaluation'
require 'reputation_system/network'
require 'reputation_system/reputation'
Expand All @@ -25,4 +24,4 @@
require 'models/rs_reputation'
require 'models/rs_reputation_message'

ActiveRecord::Base.send(:include, ReputationSystem::Base)
ActiveRecord::Base.send(:include, ReputationSystem::Base)
Binary file added lib/reputation_system/.normalization.rb.swp
Binary file not shown.
Binary file added lib/reputation_system/.reputation.rb.swp
Binary file not shown.
1 change: 0 additions & 1 deletion lib/reputation_system/base.rb
Expand Up @@ -51,7 +51,6 @@ def has_reputation(reputation_name, options)
unless ancestors.include?(ReputationSystem::Reputation)
has_many :reputations, :as => :target, :class_name => "RSReputation", :dependent => :destroy
include ReputationSystem::Query
include ReputationSystem::Normalization
include ReputationSystem::Reputation
include ReputationSystem::Scope
end
Expand Down
89 changes: 42 additions & 47 deletions lib/reputation_system/evaluation.rb
Expand Up @@ -17,7 +17,6 @@
module ReputationSystem
module Evaluation
def add_evaluation(reputation_name, value, source, *args)
raise ArgumentError, "#{reputation_name.to_s} is not defined for #{self.class.name}" unless ReputationSystem::Network.has_reputation_for?(self.class.name, reputation_name)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
Expand All @@ -27,63 +26,32 @@ def add_evaluation(reputation_name, value, source, *args)
end

def update_evaluation(reputation_name, value, source, *args)
raise ArgumentError, "#{reputation_name.to_s} is not defined for #{self.class.name}" unless ReputationSystem::Network.has_reputation_for?(self.class.name, reputation_name)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
if evaluation.nil?
raise ArgumentError, "Given instance of #{source.class.name} has not evaluated #{reputation_name} of the instance of #{self.class.name} yet."
else
oldValue = evaluation.value
evaluation.value = value
evaluation.save!
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
rep = RSReputation.find_by_reputation_name_and_target(srn, self)
RSReputation.update_reputation_value_with_updated_source(rep, evaluation, oldValue, 1, process)
end
srn, evaluation = find_srn_and_evaluation!(reputation_name, source, args.first)
oldValue = evaluation.value
evaluation.value = value
evaluation.save!
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
rep = RSReputation.find_by_reputation_name_and_target(srn, self)
RSReputation.update_reputation_value_with_updated_source(rep, evaluation, oldValue, 1, process)
end

def add_or_update_evaluation(reputation_name, value, source, *args)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
if evaluation.nil?
self.add_evaluation(reputation_name, value, source, scope)
srn, evaluation = find_srn_and_evaluation(reputation_name, source, args.first)
if RSEvaluation.exists? :reputation_name => srn, :source_id => source.id, :source_type => source.class.name, :target_id => self.id, :target_type => self.class.name
self.update_evaluation(reputation_name, value, source, *args)
else
self.update_evaluation(reputation_name, value, source, scope)
self.add_evaluation(reputation_name, value, source, *args)
end
end

def delete_evaluation(reputation_name, source, *args)
raise ArgumentError, "#{reputation_name.to_s} is not defined for #{self.class.name}" unless ReputationSystem::Network.has_reputation_for?(self.class.name, reputation_name)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
unless evaluation.nil?
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
oldValue = evaluation.value
evaluation.value = process == :product ? 1 : 0
rep = RSReputation.find_by_reputation_name_and_target(srn, self)
RSReputation.update_reputation_value_with_updated_source(rep, evaluation, oldValue, 1, process)
evaluation.destroy
end
srn, evaluation = find_srn_and_evaluation(reputation_name, source, args.first)
delete_evaluation_without_validation(srn, evaluation) if evaluation
end

def delete_evaluation!(reputation_name, source, *args)
raise ArgumentError, "#{reputation_name.to_s} is not defined for #{self.class.name}" unless ReputationSystem::Network.has_reputation_for?(self.class.name, reputation_name)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
if evaluation.nil?
raise ArgumentError, "Given instance of #{source.class.name} has not evaluated #{reputation_name} of the instance of #{self.class.name} yet."
else
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
oldValue = evaluation.value
evaluation.value = process == :product ? 1 : 0
rep = RSReputation.find_by_reputation_name_and_target(srn, self)
RSReputation.update_reputation_value_with_updated_source(rep, evaluation, oldValue, 1, process)
evaluation.destroy
end
srn, evaluation = find_srn_and_evaluation!(reputation_name, source, args.first)
delete_evaluation_without_validation(srn, evaluation)
end

def increase_evaluation(reputation_name, value, source, *args)
Expand All @@ -95,6 +63,33 @@ def decrease_evaluation(reputation_name, value, source, *args)
end

protected
def find_srn_and_evaluation(reputation_name, source, scope)
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
return srn, evaluation
end

def find_srn_and_evaluation!(reputation_name, source, scope)
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
evaluation = find_evaluation!(reputation_name, srn, source)
return srn, evaluation
end

def find_evaluation!(reputation_name, srn, source)
evaluation = RSEvaluation.find_by_reputation_name_and_source_and_target(srn, source, self)
raise ArgumentError, "Given instance of #{source.class.name} has not evaluated #{reputation_name} of the instance of #{self.class.name} yet." unless evaluation
evaluation
end

def delete_evaluation_without_validation(srn, evaluation)
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
oldValue = evaluation.value
evaluation.value = process == :product ? 1 : 0
rep = RSReputation.find_by_reputation_name_and_target(srn, self)
RSReputation.update_reputation_value_with_updated_source(rep, evaluation, oldValue, 1, process)
evaluation.destroy
end

def change_evaluation_value_by(reputation_name, value, source, *args)
scope = args.first
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
Expand Down
1 change: 1 addition & 0 deletions lib/reputation_system/network.rb
Expand Up @@ -82,6 +82,7 @@ def has_scope?(class_name, reputation_name, scope)
end

def get_scoped_reputation_name(class_name, reputation_name, scope)
raise ArgumentError, "#{reputation_name.to_s} is not defined for #{class_name}" unless has_reputation_for?(class_name, reputation_name)
scope = scope.to_sym if scope
validate_scope_necessity(class_name, reputation_name, scope)
validate_scope_existence(class_name, reputation_name, scope)
Expand Down
50 changes: 0 additions & 50 deletions lib/reputation_system/normalization.rb

This file was deleted.

41 changes: 32 additions & 9 deletions lib/reputation_system/reputation.rb
Expand Up @@ -17,23 +17,46 @@
module ReputationSystem
module Reputation
def reputation_value_for(reputation_name, *args)
scope = args.first
if !self.class.has_reputation_for?(reputation_name)
raise ArgumentError, "#{reputation_name} is not valid"
else
reputation_name = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
process = ReputationSystem::Network.get_reputation_def(self.class.name, reputation_name)[:aggregated_by]
reputation = RSReputation.find_or_create_reputation(reputation_name, self, process)
reputation.value
find_reputation(reputation_name, args.first).value
end

def normalized_reputation_value_for(reputation_name, *args)
find_reputation(reputation_name, args.first).normalized_value
end

def activate_all_reputations
RSReputation.find(:all, :conditions => {:target_id => self.id, :target_type => self.class.name, :active => false}).each do |r|
r.active = true
r.save!
end
end

def deactivate_all_reputations
RSReputation.find(:all, :conditions => {:target_id => self.id, :target_type => self.class.name, :active => true}).each do |r|
r.active = false
r.save!
end
end

def reputations_activated?(reputation_name)
r = RSReputation.find(:first, :conditions => {:reputation_name => reputation_name.to_s, :target_id => self.id, :target_type => self.class.name})
r ? r.active : false
end

def rank_for(reputation_name, *args)
scope = args.first
my_value = self.reputation_value_for(reputation_name, scope)
self.class.count_with_reputation(reputation_name, scope, :all,
:conditions => ["rs_reputations.value > ?", my_value]
) + 1
end

protected
def find_reputation(reputation_name, scope)
raise ArgumentError, "#{reputation_name} is not valid" if !self.class.has_reputation_for?(reputation_name)
srn = ReputationSystem::Network.get_scoped_reputation_name(self.class.name, reputation_name, scope)
process = ReputationSystem::Network.get_reputation_def(self.class.name, srn)[:aggregated_by]
RSReputation.find_or_create_reputation(srn, self, process)
end
end
end
end
42 changes: 1 addition & 41 deletions spec/reputation_system/normalization_spec.rb
Expand Up @@ -25,44 +25,4 @@
@phrase = Phrase.create!(:text => "One")
end

describe "#normalized_reputation_value_for" do
it "should return 0 as if there is no data" do
@question.normalized_reputation_value_for(:total_votes).should == 0
end

it "should return appropriate value in case of valid input" do
question2 = Question.create!(:text => 'Does this work too?', :author_id => @user.id)
question3 = Question.create!(:text => 'Does this work too?', :author_id => @user.id)
@question.add_evaluation(:total_votes, 1, @user)
question2.add_evaluation(:total_votes, 2, @user)
question3.add_evaluation(:total_votes, 3, @user)
@question.normalized_reputation_value_for(:total_votes).should == 0
question2.normalized_reputation_value_for(:total_votes).should == 0.5
question3.normalized_reputation_value_for(:total_votes).should == 1
end

it "should raise exception if invalid reputation name is given" do
lambda {@question.normalized_reputation_value_for(:invalid)}.should raise_error(ArgumentError)
end

it "should raise exception if scope is given for reputation with no scopes" do
lambda {@question.normalized_reputation_value_for(:difficulty, :s1)}.should raise_error(ArgumentError)
end

it "should raise exception if scope is not given for reputation with scopes" do
lambda {@phrase.normalized_reputation_value_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
end
end

describe "#exclude_all_reputations_for_normalization" do
it "should activate all reputation" do
@question2 = Question.create!(:text => 'Does this work??', :author_id => @user.id)
@question2.add_evaluation(:total_votes, 70, @user)
@question.add_evaluation(:total_votes, 100, @user)
@question.deactivate_all_reputations
RSReputation.maximum(:value, :conditions => {:reputation_name => 'total_votes', :active => true}).should == 70
@question.activate_all_reputations
RSReputation.maximum(:value, :conditions => {:reputation_name => 'total_votes', :active => true}).should == 100
end
end
end
end
43 changes: 43 additions & 0 deletions spec/reputation_system/reputation_spec.rb
Expand Up @@ -116,4 +116,47 @@
end
end
end

context "Normalization" do
describe "#normalized_reputation_value_for" do
it "should return 0 as if there is no data" do
@question.normalized_reputation_value_for(:total_votes).should == 0
end

it "should return appropriate value in case of valid input" do
question2 = Question.create!(:text => 'Does this work too?', :author_id => @user.id)
question3 = Question.create!(:text => 'Does this work too?', :author_id => @user.id)
@question.add_evaluation(:total_votes, 1, @user)
question2.add_evaluation(:total_votes, 2, @user)
question3.add_evaluation(:total_votes, 3, @user)
@question.normalized_reputation_value_for(:total_votes).should == 0
question2.normalized_reputation_value_for(:total_votes).should == 0.5
question3.normalized_reputation_value_for(:total_votes).should == 1
end

it "should raise exception if invalid reputation name is given" do
lambda {@question.normalized_reputation_value_for(:invalid)}.should raise_error(ArgumentError)
end

it "should raise exception if scope is given for reputation with no scopes" do
lambda {@question.normalized_reputation_value_for(:difficulty, :s1)}.should raise_error(ArgumentError)
end

it "should raise exception if scope is not given for reputation with scopes" do
lambda {@phrase.normalized_reputation_value_for(:difficulty_with_scope)}.should raise_error(ArgumentError)
end
end

describe "#exclude_all_reputations_for_normalization" do
it "should activate all reputation" do
@question2 = Question.create!(:text => 'Does this work??', :author_id => @user.id)
@question2.add_evaluation(:total_votes, 70, @user)
@question.add_evaluation(:total_votes, 100, @user)
@question.deactivate_all_reputations
RSReputation.maximum(:value, :conditions => {:reputation_name => 'total_votes', :active => true}).should == 70
@question.activate_all_reputations
RSReputation.maximum(:value, :conditions => {:reputation_name => 'total_votes', :active => true}).should == 100
end
end
end
end

0 comments on commit 373e665

Please sign in to comment.