VRFS-3316 : Reduce method to roll up reviews
* Creates review_summaries * Calculate and store wilson score * Unit tests
This commit is contained in:
parent
4b52d97a64
commit
2c594bf783
|
|
@ -10,11 +10,35 @@ module JamRuby
|
|||
validates :target, presence:true
|
||||
validates :user, presence:true
|
||||
validates :target_id, uniqueness: {scope: :user_id, message: "There is already a review for this User and Target."}
|
||||
|
||||
# # @options - can contain values:
|
||||
# # * target_id (optional)
|
||||
# def reduce(options)
|
||||
# arel = Review.where("deleted_at=?", nil)
|
||||
# end
|
||||
|
||||
class << self
|
||||
# Create review_summary records by grouping reviews
|
||||
def reduce()
|
||||
ReviewSummary.transaction do
|
||||
ReviewSummary.destroy_all
|
||||
Review.select("target_id, target_type AS target_type, AVG(rating) as avg_rating, count(*) as review_count, SUM(CASE WHEN rating>=3.0 THEN 1 ELSE 0 END) AS pos_count").group("target_type, target_id")
|
||||
.each do |r|
|
||||
#puts "Reducing reviews: #{r.inspect} #{r.pos_count} / #{r.review_count}"
|
||||
ReviewSummary.create!(
|
||||
target_id: r.target_id,
|
||||
target_type: r.target_type,
|
||||
avg_rating: r.avg_rating,
|
||||
wilson_score: ci_lower_bound(r.pos_count, r.review_count),
|
||||
review_count: r.review_count
|
||||
)
|
||||
end # each
|
||||
end # transaction
|
||||
end # reduce
|
||||
|
||||
def ci_lower_bound(pos, n, confidence=0.95)
|
||||
pos=pos.to_f
|
||||
n=n.to_f
|
||||
return 0 if n == 0
|
||||
z = 1.96 # Statistics2.pnormaldist(1-(1-confidence)/2)
|
||||
phat = 1.0*pos/n
|
||||
(phat + z*z/(2*n) - z * Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n)
|
||||
end
|
||||
|
||||
end # self
|
||||
end
|
||||
end
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
module JamRuby
|
||||
class ReviewSummary < ActiveRecord::Base
|
||||
attr_accessible :target, :target_type, :avg_rating, :wilson_score, :review_count
|
||||
attr_accessible :target, :target_id, :target_type, :avg_rating, :wilson_score, :review_count
|
||||
belongs_to :target, polymorphic: true
|
||||
|
||||
validates :avg_rating, presence:true, numericality: true
|
||||
validates :review_count, presence:true, numericality: {only_integer: true}
|
||||
validates :wilson_score, presence:true, numericality: {greater_than:0, less_than:1}
|
||||
validates :target, presence:true
|
||||
validates :target_id, uniqueness:true
|
||||
validates :target_id, presence:true, uniqueness:true
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -139,6 +139,17 @@ FactoryGirl.define do
|
|||
end
|
||||
end
|
||||
|
||||
factory :review, :class => JamRuby::Review do
|
||||
sequence(:name) { |n| "Band" }
|
||||
biography "My Biography"
|
||||
city "Apex"
|
||||
state "NC"
|
||||
country "US"
|
||||
before(:create) { |review|
|
||||
review.genres << Genre.first
|
||||
}
|
||||
end
|
||||
|
||||
factory :music_session, :class => JamRuby::MusicSession do
|
||||
sequence(:name) { |n| "Music Session #{n}" }
|
||||
sequence(:description) { |n| "Music Session Description #{n}" }
|
||||
|
|
|
|||
|
|
@ -46,8 +46,33 @@ describe Review do
|
|||
review2 = Review.create(target:target, rating:3, user:@user)
|
||||
review2.valid?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "reduces" do
|
||||
review = Review.create(target:target, rating:3, user:@user)
|
||||
review.valid?.should be_true
|
||||
|
||||
review2 = Review.create(target:target, rating:5, user:FactoryGirl.create(:user))
|
||||
review2.valid?.should be_true
|
||||
Review.count.should eq(2)
|
||||
ReviewSummary.count.should eq(0)
|
||||
Review.reduce()
|
||||
ReviewSummary.count.should eq(1)
|
||||
ReviewSummary.first.avg_rating.should eq(4.0)
|
||||
|
||||
puts "ORIG: #{ReviewSummary.all.inspect}"
|
||||
ws_orig = ReviewSummary.first.wilson_score
|
||||
avg_orig = ReviewSummary.first.avg_rating
|
||||
|
||||
5.times {Review.create(target:target, rating:5, user:FactoryGirl.create(:user))}
|
||||
Review.reduce()
|
||||
|
||||
ReviewSummary.first.wilson_score.should > ws_orig
|
||||
ReviewSummary.first.avg_rating.should > avg_orig
|
||||
|
||||
puts "ALL: #{ReviewSummary.all.inspect}"
|
||||
end
|
||||
end # context
|
||||
|
||||
context "validates review summary" do
|
||||
it "blank target" do
|
||||
review_summary = ReviewSummary.create()
|
||||
|
|
@ -99,4 +124,5 @@ describe Review do
|
|||
it_behaves_like :review, @jam_track, "jam_track"
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
Loading…
Reference in New Issue