@@ -6,6 +6,7 @@ class Debate < ActiveRecord::Base
|
||||
include Measurable
|
||||
include Sanitizable
|
||||
include PgSearch
|
||||
include SearchCache
|
||||
include Filterable
|
||||
|
||||
apply_simple_captcha
|
||||
@@ -41,21 +42,28 @@ class Debate < ActiveRecord::Base
|
||||
visitable # Ahoy will automatically assign visit_id on create
|
||||
|
||||
pg_search_scope :pg_search, {
|
||||
against: {
|
||||
title: 'A',
|
||||
description: 'B'
|
||||
},
|
||||
associated_against: {
|
||||
tags: :name
|
||||
},
|
||||
against: :ignored, # not used since the using: option has a tsvector_column
|
||||
using: {
|
||||
tsearch: { dictionary: "spanish" },
|
||||
tsearch: { dictionary: "spanish", tsvector_column: 'tsv', prefix: true }
|
||||
},
|
||||
ignoring: :accents,
|
||||
ranked_by: '(:tsearch)',
|
||||
order_within_rank: "debates.cached_votes_up DESC"
|
||||
}
|
||||
|
||||
def searchable_values
|
||||
{ title => 'A',
|
||||
author.username => 'B',
|
||||
tag_list.join(' ') => 'B',
|
||||
geozone.try(:name) => 'B',
|
||||
description => 'D'
|
||||
}
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
self.pg_search(terms)
|
||||
end
|
||||
|
||||
def description
|
||||
super.try :html_safe
|
||||
end
|
||||
@@ -121,15 +129,6 @@ class Debate < ActiveRecord::Base
|
||||
cached_votes_up)
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
return none unless terms.present?
|
||||
|
||||
debate_ids = where("debates.title ILIKE ? OR debates.description ILIKE ?",
|
||||
"%#{terms}%", "%#{terms}%").pluck(:id)
|
||||
tag_ids = tagged_with(terms, wild: true, any: true).pluck(:id)
|
||||
where(id: [debate_ids, tag_ids].flatten.compact)
|
||||
end
|
||||
|
||||
def after_hide
|
||||
self.tags.each{ |t| t.decrement_custom_counter_for('Debate') }
|
||||
end
|
||||
|
||||
13
db/migrate/20160204134022_add_tsvector_to_debates.rb
Normal file
13
db/migrate/20160204134022_add_tsvector_to_debates.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class AddTsvectorToDebates < ActiveRecord::Migration
|
||||
|
||||
def up
|
||||
add_column :debates, :tsv, :tsvector
|
||||
add_index :debates, :tsv, using: "gin"
|
||||
end
|
||||
|
||||
def down
|
||||
remove_index :debates, :tsv
|
||||
remove_column :debates, :tsv
|
||||
end
|
||||
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160126090634) do
|
||||
ActiveRecord::Schema.define(version: 20160204134022) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -120,6 +120,7 @@ ActiveRecord::Schema.define(version: 20160126090634) do
|
||||
t.integer "confidence_score", default: 0
|
||||
t.string "external_link", limit: 100
|
||||
t.integer "geozone_id"
|
||||
t.tsvector "tsv"
|
||||
end
|
||||
|
||||
add_index "debates", ["author_id", "hidden_at"], name: "index_debates_on_author_id_and_hidden_at", using: :btree
|
||||
@@ -134,6 +135,7 @@ ActiveRecord::Schema.define(version: 20160126090634) do
|
||||
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
|
||||
add_index "debates", ["title"], name: "index_debates_on_title", using: :btree
|
||||
add_index "debates", ["tsv"], name: "index_debates_on_tsv", using: :gin
|
||||
|
||||
create_table "delayed_jobs", force: :cascade do |t|
|
||||
t.integer "priority", default: 0, null: false
|
||||
|
||||
@@ -778,32 +778,32 @@ feature 'Debates' do
|
||||
end
|
||||
end
|
||||
|
||||
xscenario "Order by relevance by default", :js do
|
||||
scenario "Order by relevance by default", :js do
|
||||
debate1 = create(:debate, title: "Show you got", cached_votes_up: 10)
|
||||
debate2 = create(:debate, title: "Show what you got", cached_votes_up: 1)
|
||||
debate3 = create(:debate, title: "Show you got", cached_votes_up: 100)
|
||||
|
||||
visit debates_path
|
||||
fill_in "search", with: "Show what you got"
|
||||
fill_in "search", with: "Show you got"
|
||||
click_button "Search"
|
||||
|
||||
expect(page).to have_selector("a.active", text: "relevance")
|
||||
|
||||
within("#debates") do
|
||||
expect(all(".debate")[0].text).to match "Show what you got"
|
||||
expect(all(".debate")[0].text).to match "Show you got"
|
||||
expect(all(".debate")[1].text).to match "Show you got"
|
||||
expect(all(".debate")[2].text).to match "Show you got"
|
||||
expect(all(".debate")[2].text).to match "Show what you got"
|
||||
end
|
||||
end
|
||||
|
||||
xscenario "Reorder results maintaing search", :js do
|
||||
scenario "Reorder results maintaing search", :js do
|
||||
debate1 = create(:debate, title: "Show you got", cached_votes_up: 10, created_at: 1.week.ago)
|
||||
debate2 = create(:debate, title: "Show what you got", cached_votes_up: 1, created_at: 1.month.ago)
|
||||
debate3 = create(:debate, title: "Show you got", cached_votes_up: 100, created_at: Time.now)
|
||||
debate4 = create(:debate, title: "Do not display", cached_votes_up: 1, created_at: 1.week.ago)
|
||||
|
||||
visit debates_path
|
||||
fill_in "search", with: "Show what you got"
|
||||
fill_in "search", with: "Show you got"
|
||||
click_button "Search"
|
||||
click_link 'newest'
|
||||
expect(page).to have_selector("a.active", text: "newest")
|
||||
@@ -960,12 +960,12 @@ feature 'Debates' do
|
||||
debate5 = create(:debate, title: "Fifth debate has 5 votes", cached_votes_up: 5)
|
||||
debate6 = create(:debate, title: "Sixth debate has 6 votes", description: 'This is the sixth debate', cached_votes_up: 6)
|
||||
debate7 = create(:debate, title: "This has seven votes, and is not suggest", description: 'This is the seven', cached_votes_up: 7)
|
||||
|
||||
|
||||
visit new_debate_path
|
||||
fill_in 'debate_title', with: 'debate'
|
||||
fill_in 'debate_title', with: 'debate'
|
||||
check "debate_terms_of_service"
|
||||
|
||||
within('div#js-suggest') do
|
||||
within('div#js-suggest') do
|
||||
expect(page).to have_content ("You are seeing 5 of 6 debates containing the term 'debate'")
|
||||
end
|
||||
end
|
||||
@@ -976,14 +976,14 @@ feature 'Debates' do
|
||||
|
||||
debate1 = create(:debate, title: "First debate has 10 vote", cached_votes_up: 10)
|
||||
debate2 = create(:debate, title: "Second debate has 2 votes", cached_votes_up: 2)
|
||||
|
||||
|
||||
visit new_debate_path
|
||||
fill_in 'debate_title', with: 'proposal'
|
||||
check "debate_terms_of_service"
|
||||
check "debate_terms_of_service"
|
||||
|
||||
within('div#js-suggest') do
|
||||
expect(page).to_not have_content ('You are seeing')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -436,26 +436,26 @@ describe Debate do
|
||||
|
||||
context "attributes" do
|
||||
|
||||
xit "searches by title" do
|
||||
it "searches by title" do
|
||||
debate = create(:debate, title: 'save the world')
|
||||
results = Debate.search('save the world')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
xit "searches by description" do
|
||||
it "searches by description" do
|
||||
debate = create(:debate, description: 'in order to save the world one must think about...')
|
||||
results = Debate.search('one must think')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
xit "searches by author name" do
|
||||
it "searches by author name" do
|
||||
author = create(:user, username: 'Danny Trejo')
|
||||
debate = create(:debate, author: author)
|
||||
results = Debate.search('Danny')
|
||||
expect(results).to eq([debate])
|
||||
end
|
||||
|
||||
xit "searches by geozone" do
|
||||
it "searches by geozone" do
|
||||
geozone = create(:geozone, name: 'California')
|
||||
debate = create(:debate, geozone: geozone)
|
||||
results = Debate.search('California')
|
||||
@@ -466,7 +466,7 @@ describe Debate do
|
||||
|
||||
context "stemming" do
|
||||
|
||||
xit "searches word stems" do
|
||||
it "searches word stems" do
|
||||
debate = create(:debate, title: 'limpiar')
|
||||
|
||||
results = Debate.search('limpiará')
|
||||
@@ -483,7 +483,7 @@ describe Debate do
|
||||
|
||||
context "accents" do
|
||||
|
||||
xit "searches with accents" do
|
||||
it "searches with accents" do
|
||||
debate = create(:debate, title: 'difusión')
|
||||
|
||||
results = Debate.search('difusion')
|
||||
@@ -492,13 +492,16 @@ describe Debate do
|
||||
debate2 = create(:debate, title: 'estadisticas')
|
||||
results = Debate.search('estadísticas')
|
||||
expect(results).to eq([debate2])
|
||||
|
||||
debate3 = create(:debate, title: 'público')
|
||||
results = Debate.search('publico')
|
||||
expect(results).to eq([debate3])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "case" do
|
||||
|
||||
xit "searches case insensite" do
|
||||
it "searches case insensite" do
|
||||
debate = create(:debate, title: 'SHOUT')
|
||||
|
||||
results = Debate.search('shout')
|
||||
@@ -508,27 +511,23 @@ describe Debate do
|
||||
results = Debate.search("SCREAM")
|
||||
expect(results).to eq([debate2])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "typos" do
|
||||
context "tags" do
|
||||
it "searches by tags" do
|
||||
debate = create(:debate, tag_list: 'Latina')
|
||||
|
||||
xit "searches with typos" do
|
||||
debate = create(:debate, title: 'difusión')
|
||||
results = Debate.search('Latina')
|
||||
expect(results.first).to eq(debate)
|
||||
|
||||
results = Debate.search('difuon')
|
||||
expect(results).to eq([debate])
|
||||
|
||||
debate2 = create(:debate, title: 'desarrollo')
|
||||
results = Debate.search('desarolo')
|
||||
expect(results).to eq([debate2])
|
||||
results = Debate.search('Latin')
|
||||
expect(results.first).to eq(debate)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "order" do
|
||||
|
||||
xit "orders by weight" do
|
||||
it "orders by weight" do
|
||||
debate_description = create(:debate, description: 'stop corruption')
|
||||
debate_title = create(:debate, title: 'stop corruption')
|
||||
|
||||
@@ -538,7 +537,7 @@ describe Debate do
|
||||
expect(results.second).to eq(debate_description)
|
||||
end
|
||||
|
||||
xit "orders by weight and then votes" do
|
||||
it "orders by weight and then votes" do
|
||||
title_some_votes = create(:debate, title: 'stop corruption', cached_votes_up: 5)
|
||||
title_least_voted = create(:debate, title: 'stop corruption', cached_votes_up: 2)
|
||||
title_most_voted = create(:debate, title: 'stop corruption', cached_votes_up: 10)
|
||||
@@ -547,28 +546,26 @@ describe Debate do
|
||||
results = Debate.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(title_most_voted)
|
||||
expect(results.second).to eq(description_most_voted)
|
||||
expect(results.third).to eq(title_some_votes)
|
||||
expect(results.fourth).to eq(title_least_voted)
|
||||
expect(results.second).to eq(title_some_votes)
|
||||
expect(results.third).to eq(title_least_voted)
|
||||
expect(results.fourth).to eq(description_most_voted)
|
||||
end
|
||||
|
||||
xit "orders by weight and then votes and then created_at" do
|
||||
newest = create(:debate, title: 'stop corruption', cached_votes_up: 5, created_at: Time.now)
|
||||
oldest = create(:debate, title: 'stop corruption', cached_votes_up: 5, created_at: 1.month.ago)
|
||||
old = create(:debate, title: 'stop corruption', cached_votes_up: 5, created_at: 1.week.ago)
|
||||
it "gives much more weight to word matches than votes" do
|
||||
exact_title_few_votes = create(:debate, title: 'stop corruption', cached_votes_up: 5)
|
||||
similar_title_many_votes = create(:debate, title: 'stop some of the corruption', cached_votes_up: 500)
|
||||
|
||||
results = Debate.search('stop corruption')
|
||||
|
||||
expect(results.first).to eq(newest)
|
||||
expect(results.second).to eq(old)
|
||||
expect(results.third).to eq(oldest)
|
||||
expect(results.first).to eq(exact_title_few_votes)
|
||||
expect(results.second).to eq(similar_title_many_votes)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "reorder" do
|
||||
|
||||
xit "should be able to reorder by hot_score after searching" do
|
||||
it "should be able to reorder by hot_score after searching" do
|
||||
lowest_score = create(:debate, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:debate, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:debate, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -590,7 +587,7 @@ describe Debate do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
xit "should be able to reorder by confidence_score after searching" do
|
||||
it "should be able to reorder by confidence_score after searching" do
|
||||
lowest_score = create(:debate, title: 'stop corruption', cached_votes_up: 1)
|
||||
highest_score = create(:debate, title: 'stop corruption', cached_votes_up: 2)
|
||||
average_score = create(:debate, title: 'stop corruption', cached_votes_up: 3)
|
||||
@@ -612,7 +609,7 @@ describe Debate do
|
||||
expect(results.third).to eq(lowest_score)
|
||||
end
|
||||
|
||||
xit "should be able to reorder by created_at after searching" do
|
||||
it "should be able to reorder by created_at after searching" do
|
||||
recent = create(:debate, title: 'stop corruption', cached_votes_up: 1, created_at: 1.week.ago)
|
||||
newest = create(:debate, title: 'stop corruption', cached_votes_up: 2, created_at: Time.now)
|
||||
oldest = create(:debate, title: 'stop corruption', cached_votes_up: 3, created_at: 1.month.ago)
|
||||
@@ -630,7 +627,7 @@ describe Debate do
|
||||
expect(results.third).to eq(oldest)
|
||||
end
|
||||
|
||||
xit "should be able to reorder by most commented after searching" do
|
||||
it "should be able to reorder by most commented after searching" do
|
||||
least_commented = create(:debate, title: 'stop corruption', cached_votes_up: 1, comments_count: 1)
|
||||
most_commented = create(:debate, title: 'stop corruption', cached_votes_up: 2, comments_count: 100)
|
||||
some_comments = create(:debate, title: 'stop corruption', cached_votes_up: 3, comments_count: 10)
|
||||
@@ -650,41 +647,30 @@ describe Debate do
|
||||
|
||||
end
|
||||
|
||||
context "tags" do
|
||||
|
||||
xit "searches by tags" do
|
||||
debate = create(:debate, tag_list: 'Latina')
|
||||
|
||||
results = Debate.search('Latina')
|
||||
expect(results.first).to eq(debate)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "no results" do
|
||||
|
||||
xit "no words match" do
|
||||
it "no words match" do
|
||||
debate = create(:debate, title: 'save world')
|
||||
|
||||
results = Debate.search('destroy planet')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
xit "too many typos" do
|
||||
it "too many typos" do
|
||||
debate = create(:debate, title: 'fantastic')
|
||||
|
||||
results = Debate.search('frantac')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
xit "too much stemming" do
|
||||
it "too much stemming" do
|
||||
debate = create(:debate, title: 'reloj')
|
||||
|
||||
results = Debate.search('superrelojimetro')
|
||||
expect(results).to eq([])
|
||||
end
|
||||
|
||||
xit "empty" do
|
||||
it "empty" do
|
||||
debate = create(:debate, title: 'great')
|
||||
|
||||
results = Debate.search('')
|
||||
|
||||
Reference in New Issue
Block a user