From 96ae7575b1d2b2e1d47ce02615d26ec39ee0c4af Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 8 Sep 2015 14:40:14 +0200 Subject: [PATCH 1/3] adds confidence_score to debates --- app/models/debate.rb | 9 +++++++-- ...8102936_add_confidence_score_to_debates.rb | 6 ++++++ db/schema.rb | 4 +++- spec/factories.rb | 4 ++++ spec/models/debate_spec.rb | 20 +++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20150908102936_add_confidence_score_to_debates.rb diff --git a/app/models/debate.rb b/app/models/debate.rb index e8855086a..b118e8a89 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -21,7 +21,7 @@ class Debate < ActiveRecord::Base before_validation :sanitize_description before_validation :sanitize_tag_list - before_save :calculate_hot_score + before_save :calculate_hot_score, :calculate_confidence_score scope :sort_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) } scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) } @@ -29,7 +29,7 @@ class Debate < ActiveRecord::Base scope :flagged, -> { where("flags_count > 0") } scope :for_render, -> { includes(:tags) } scope :sort_by_hot_score , -> { order(hot_score: :desc) } - scope :sort_by_score , -> { order(cached_votes_score: :desc) } + scope :sort_by_confidence_score , -> { order(confidence_score: :desc) } scope :sort_by_created_at, -> { order(created_at: :desc) } scope :sort_by_most_commented, -> { order(comments_count: :desc) } scope :sort_by_random, -> { order("RANDOM()") } @@ -130,6 +130,11 @@ class Debate < ActiveRecord::Base self.hot_score = (age_in_units**3 + weighted_score * 1000).round end + def calculate_confidence_score + return unless cached_votes_total > 0 + self.confidence_score = cached_votes_score * cached_votes_up / cached_votes_total + end + def self.search(terms) terms.present? ? where("title ILIKE ? OR description ILIKE ?", "%#{terms}%", "%#{terms}%") : none end diff --git a/db/migrate/20150908102936_add_confidence_score_to_debates.rb b/db/migrate/20150908102936_add_confidence_score_to_debates.rb new file mode 100644 index 000000000..b0494a839 --- /dev/null +++ b/db/migrate/20150908102936_add_confidence_score_to_debates.rb @@ -0,0 +1,6 @@ +class AddConfidenceScoreToDebates < ActiveRecord::Migration + def change + add_column :debates, :confidence_score, :integer, default: 0 + add_index :debates, :confidence_score + end +end diff --git a/db/schema.rb b/db/schema.rb index 8e4dca776..f1b4dfe76 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150907064631) do +ActiveRecord::Schema.define(version: 20150908102936) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -102,12 +102,14 @@ ActiveRecord::Schema.define(version: 20150907064631) do t.integer "cached_anonymous_votes_total", default: 0 t.integer "cached_votes_score", default: 0 t.integer "hot_score", limit: 8, default: 0 + t.integer "confidence_score", default: 0 end add_index "debates", ["cached_votes_down"], name: "index_debates_on_cached_votes_down", using: :btree add_index "debates", ["cached_votes_score"], name: "index_debates_on_cached_votes_score", using: :btree add_index "debates", ["cached_votes_total"], name: "index_debates_on_cached_votes_total", using: :btree add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree + add_index "debates", ["confidence_score"], name: "index_debates_on_confidence_score", using: :btree add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree add_index "debates", ["hot_score"], name: "index_debates_on_hot_score", using: :btree diff --git a/spec/factories.rb b/spec/factories.rb index deaaee98d..f779f2e32 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -78,6 +78,10 @@ FactoryGirl.define do before(:save) { |d| d.calculate_hot_score } end + trait :with_confidence_score do + before(:save) { |d| d.calculate_confidence_score } + end + trait :conflictive do after :create do |debate| Flag.flag(FactoryGirl.create(:user), debate) diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index 5ee0d7243..a2262f909 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -236,6 +236,26 @@ describe Debate do expect(previous).to be < debate.hot_score end end + end + + describe "#confidence_score" do + + it "takes into account percentage of total votes and total_positive and total negative votes" do + debate = create(:debate, :with_confidence_score, cached_votes_up: 100, cached_votes_score: 100, cached_votes_total: 100) + expect(debate.confidence_score).to eq(100) + + debate = create(:debate, :with_confidence_score, cached_votes_up: 0, cached_votes_score: -100, cached_votes_total: 100) + expect(debate.confidence_score).to eq(0) + + debate = create(:debate, :with_confidence_score, cached_votes_up: 50, cached_votes_score: 50, cached_votes_total: 100) + expect(debate.confidence_score).to eq(25) + + debate = create(:debate, :with_confidence_score, cached_votes_up: 500, cached_votes_score: 500, cached_votes_total: 1000) + expect(debate.confidence_score).to eq(250) + + debate = create(:debate, :with_confidence_score, cached_votes_up: 10, cached_votes_score: -80, cached_votes_total: 100) + expect(debate.confidence_score).to eq(-8) + end end From 339e9782370e16c0c9b309ee4353b61696b495aa Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 8 Sep 2015 14:40:49 +0200 Subject: [PATCH 2/3] default order confidence_score for home and debate index --- app/controllers/debates_controller.rb | 2 +- app/controllers/welcome_controller.rb | 2 +- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- spec/features/debates_spec.rb | 22 +++++++++++----------- spec/features/home_spec.rb | 11 +++++++++++ 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index 78a465572..b336a924a 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -83,7 +83,7 @@ class DebatesController < ApplicationController end def parse_order - @valid_orders = ['hot_score', 'created_at', 'score', 'most_commented', 'random'] + @valid_orders = ['confidence_score', 'hot_score', 'created_at', 'most_commented', 'random'] @order = @valid_orders.include?(params[:order]) ? params[:order] : @valid_orders.first end diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index ca3d04d68..6c1badca2 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -2,7 +2,7 @@ class WelcomeController < ApplicationController skip_authorization_check def index - @featured_debates = Debate.sort_by_hot_score.limit(3).for_render + @featured_debates = Debate.sort_by_confidence_score.limit(3).for_render set_debate_votes(@featured_debates) end diff --git a/config/locales/en.yml b/config/locales/en.yml index af4a29659..d0d0d42a5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -71,9 +71,9 @@ en: select_order: Order by select_order_long: Order debates by orders: + confidence_score: best rated hot_score: most active created_at: newest - score: best rated most_commented: most commented random: random filter_topic: diff --git a/config/locales/es.yml b/config/locales/es.yml index f86723631..8dbeec62d 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -71,9 +71,9 @@ es: select_order: Ordenar por select_order_long: Estás viendo los debates orders: + confidence_score: "mejor valorados" hot_score: "más activos" created_at: "más nuevos" - score: "mejor valorados" most_commented: "más comentados" random: "aleatorio" filter_topic: diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index 1c8cdf6cc..330508e88 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -359,10 +359,10 @@ feature 'Debates' do feature 'Debate index order filters' do - scenario 'Default order is hot_score', :js do - create(:debate, title: 'best').update_column(:hot_score, 10) - create(:debate, title: 'worst').update_column(:hot_score, 2) - create(:debate, title: 'medium').update_column(:hot_score, 5) + scenario 'Default order is confidence_score', :js do + create(:debate, title: 'best').update_column(:confidence_score, 10) + create(:debate, title: 'worst').update_column(:confidence_score, 2) + create(:debate, title: 'medium').update_column(:confidence_score, 5) visit debates_path @@ -370,20 +370,20 @@ feature 'Debates' do expect('medium').to appear_before('worst') end - scenario 'Debates are ordered by best rated', :js do - create(:debate, title: 'best', cached_votes_score: 10) - create(:debate, title: 'medium', cached_votes_score: 5) - create(:debate, title: 'worst', cached_votes_score: 2) + scenario 'Debates are ordered by hot_score', :js do + create(:debate, title: 'best').update_column(:hot_score, 10) + create(:debate, title: 'worst').update_column(:hot_score, 2) + create(:debate, title: 'medium').update_column(:hot_score, 5) visit debates_path - select 'best rated', from: 'order-selector' + select 'most active', from: 'order-selector' - within '#debates.js-order-score' do + within '#debates.js-order-hot-score' do expect('best').to appear_before('medium') expect('medium').to appear_before('worst') end - expect(current_url).to include('order=score') + expect(current_url).to include('order=hot_score') end scenario 'Debates are ordered by most commented', :js do diff --git a/spec/features/home_spec.rb b/spec/features/home_spec.rb index fcad1ca24..ff87a294b 100644 --- a/spec/features/home_spec.rb +++ b/spec/features/home_spec.rb @@ -17,4 +17,15 @@ feature "Home" do end + scenario "Order by confidence score" do + create(:debate, confidence_score: 100, title: 'best') + create(:debate, confidence_score: -20, title: 'worst') + create(:debate, confidence_score: 50, title: 'medium') + + visit root_path + + expect('best').to appear_before('medium') + expect('medium').to appear_before('worst') + end + end From e49695ba5e92f126af2b03126ed1912c3d19e51b Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 8 Sep 2015 14:56:52 +0200 Subject: [PATCH 3/3] adds confidence_score specs --- spec/models/debate_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index a2262f909..07e50ad14 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -257,6 +257,23 @@ describe Debate do expect(debate.confidence_score).to eq(-8) end + describe 'actions which affect it' do + let(:debate) { create(:debate, :with_confidence_score) } + + it "increases with like" do + previous = debate.confidence_score + 5.times { debate.register_vote(create(:user), true) } + expect(previous).to be < debate.confidence_score + end + + it "decreases with dislikes" do + debate.register_vote(create(:user), true) + previous = debate.confidence_score + 3.times { debate.register_vote(create(:user), false) } + expect(previous).to be > debate.confidence_score + end + end + end describe "self.search" do