Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix a bug associated with add_or_update_evaluation method that happen…

…s when source uses STI.
  • Loading branch information...
commit 579c2fe8a8b116461461adfeee570b460067fd77 1 parent 6367c9f
Katsuya Noguchi authored
2  CHANGELOG.md
View
@@ -1,3 +1,5 @@
+* Fix a bug associated with `add_or_update_evaluation` method that happens when source uses STI.
+
## ActiveRecordReputationSystem 2.0.1 ##
* Print out future deprecation warning for methods `with_reputation` and `with_normalized_reputation`.
20 lib/reputation_system/models/evaluation.rb
View
@@ -32,7 +32,7 @@ class Evaluation < ActiveRecord::Base
validate :source_must_be_defined_for_reputation_in_network
def self.find_by_reputation_name_and_source_and_target(reputation_name, source, target)
- source_type = get_source_type_for_sti(source, target.class.name, reputation_name)
+ source_type = get_source_type_for_sti(source.class.name, target.class.name, reputation_name)
ReputationSystem::Evaluation.find(:first,
:conditions => {:reputation_name => reputation_name.to_s,
:source_id => source.id,
@@ -48,11 +48,23 @@ def self.create_evaluation(reputation_name, value, source, target)
:target_id => target.id, :target_type => target.class.name)
end
+ # Override exists? class method.
+ class << self
+ alias :original_exists? :exists?
+
+ def exists?(options={})
+ if options[:source_type] && options[:target_type] && options[:reputation_name]
+ options[:source_type] = get_source_type_for_sti(options[:source_type], options[:target_type], options[:reputation_name])
+ end
+ original_exists? options
+ end
+ end
+
protected
- def self.get_source_type_for_sti(source, target_type, reputation_name)
+ def self.get_source_type_for_sti(source_type, target_type, reputation_name)
valid_source_type = ReputationSystem::Network.get_reputation_def(target_type, reputation_name)[:source].to_s.camelize
- source_class = source.class
+ source_class = source_type.constantize
while source_class && valid_source_type != source_class.name && source_class.name != "ActiveRecord::Base"
source_class = source_class.superclass
end
@@ -60,7 +72,7 @@ def self.get_source_type_for_sti(source, target_type, reputation_name)
end
def set_source_type_for_sti
- sti_source_type = self.class.get_source_type_for_sti(source, target_type, reputation_name)
+ sti_source_type = self.class.get_source_type_for_sti(source_type, target_type, reputation_name)
self.source_type = sti_source_type if sti_source_type
end
14 spec/reputation_system/evaluation_methods_spec.rb
View
@@ -140,7 +140,7 @@
lambda { answer.add_evaluation(:avg_rating, 3, @user) }.should_not raise_error
end
- context "With Scopes" do
+ context "with scopes" do
it "should add evaluation on appropriate scope" do
@phrase.add_evaluation(:difficulty_with_scope, 1, @user, :s1).should be_true
@phrase.add_evaluation(:difficulty_with_scope, 2, @user, :s2).should be_true
@@ -171,7 +171,7 @@
@question.reputation_for(:total_votes).should == 2
end
- context "With Scopes" do
+ context "with scopes" do
it "should add evaluation on appropriate scope if it does not exist" do
@phrase.add_or_update_evaluation(:difficulty_with_scope, 1, @user, :s1).should be_true
@phrase.add_or_update_evaluation(:difficulty_with_scope, 2, @user, :s2).should be_true
@@ -190,6 +190,16 @@
@phrase.reputation_for(:difficulty_with_scope, :s3).should == 0
end
end
+
+ context "with STI" do
+ it "should be able to update evaluation by an object of a class with sti" do
+ @post = Post.create! :name => "Post1"
+ @designer = Designer.create! :name => "John"
+ @post.add_or_update_evaluation(:votes, 1, @designer)
+ @post.add_or_update_evaluation(:votes, -1, @designer)
+ @post.reputation_for(:votes).should == -1
+ end
+ end
end
describe "#update_evaluation" do
14 spec/spec_helper.rb
View
@@ -108,6 +108,11 @@
t.string :type
t.timestamps
end
+
+ create_table :posts do |t|
+ t.string :name
+ t.timestamps
+ end
end
class User < ActiveRecord::Base
@@ -193,6 +198,8 @@ class Translation < ActiveRecord::Base
:source_of => { :reputation => :maturity, :of => :phrase, :scope => :locale}
end
+# For STI Specs
+
class Person < ActiveRecord::Base
has_reputation :leadership,
:source => :person,
@@ -204,3 +211,10 @@ class Programmer < Person
class Designer < Person
end
+
+class Post < ActiveRecord::Base
+ belongs_to :person
+
+ has_reputation :votes,
+ :source => :person
+end
Please sign in to comment.
Something went wrong with that request. Please try again.