diff options
author | Matt Jankowski <mjankowski@thoughtbot.com> | 2017-04-09 08:45:01 -0400 |
---|---|---|
committer | Eugen <eugen@zeonfederated.com> | 2017-04-09 14:45:01 +0200 |
commit | 388ec0d5b6d1549abed15802d6bdbfc8b1c05294 (patch) | |
tree | 218a713f7bd177f964f44a4c3fe0092bddfc5382 | |
parent | 71706f21c28f5ae623ee69810fe26a34fb79b446 (diff) |
Search cleanup (#1333)
* Clean up SQL output in Tag and Account search methods * Add basic coverage for Tag.search_for * Add coverage for Account.search_for * Add coverage for Account.advanced_search_for
-rw-r--r-- | app/models/account.rb | 12 | ||||
-rw-r--r-- | app/models/tag.rb | 4 | ||||
-rw-r--r-- | spec/models/account_spec.rb | 55 | ||||
-rw-r--r-- | spec/models/tag_spec.rb | 11 |
4 files changed, 74 insertions, 8 deletions
diff --git a/app/models/account.rb b/app/models/account.rb index cbba8b5b6..c59c76009 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -203,7 +203,7 @@ class Account < ApplicationRecord end def triadic_closures(account, limit = 5) - sql = <<SQL + sql = <<-SQL.squish WITH first_degree AS ( SELECT target_account_id FROM follows @@ -216,7 +216,7 @@ class Account < ApplicationRecord GROUP BY target_account_id, accounts.id ORDER BY count(account_id) DESC LIMIT ? -SQL + SQL Account.find_by_sql([sql, account.id, account.id, limit]) end @@ -226,7 +226,7 @@ SQL textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))' query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')' - sql = <<SQL + sql = <<-SQL.squish SELECT accounts.*, ts_rank_cd(#{textsearch}, #{query}, 32) AS rank @@ -234,7 +234,7 @@ SQL WHERE #{query} @@ #{textsearch} ORDER BY rank DESC LIMIT ? -SQL + SQL Account.find_by_sql([sql, limit]) end @@ -244,7 +244,7 @@ SQL textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))' query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')' - sql = <<SQL + sql = <<-SQL.squish SELECT accounts.*, (count(f.id) + 1) * ts_rank_cd(#{textsearch}, #{query}, 32) AS rank @@ -254,7 +254,7 @@ SQL GROUP BY accounts.id ORDER BY rank DESC LIMIT ? -SQL + SQL Account.find_by_sql([sql, account.id, account.id, limit]) end diff --git a/app/models/tag.rb b/app/models/tag.rb index 15625ca43..6209d7dab 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -17,7 +17,7 @@ class Tag < ApplicationRecord textsearch = 'to_tsvector(\'simple\', tags.name)' query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')' - sql = <<SQL + sql = <<-SQL.squish SELECT tags.*, ts_rank_cd(#{textsearch}, #{query}) AS rank @@ -25,7 +25,7 @@ class Tag < ApplicationRecord WHERE #{query} @@ #{textsearch} ORDER BY rank DESC LIMIT ? -SQL + SQL Tag.find_by_sql([sql, limit]) end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 93a45459d..0c3b2b042 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -170,6 +170,61 @@ RSpec.describe Account, type: :model do end end + describe '.search_for' do + before do + @match = Fabricate( + :account, + display_name: "Display Name", + username: "username", + domain: "example.com" + ) + _missing = Fabricate( + :account, + display_name: "Missing", + username: "missing", + domain: "missing.com" + ) + end + + it 'finds accounts with matching display_name' do + results = Account.search_for("display") + expect(results).to eq [@match] + end + + it 'finds accounts with matching username' do + results = Account.search_for("username") + expect(results).to eq [@match] + end + + it 'finds accounts with matching domain' do + results = Account.search_for("example") + expect(results).to eq [@match] + end + + it 'ranks multiple matches higher' do + account = Fabricate( + :account, + username: "username", + display_name: "username" + ) + results = Account.search_for("username") + expect(results).to eq [account, @match] + end + end + + describe '.advanced_search_for' do + it 'ranks followed accounts higher' do + account = Fabricate(:account) + match = Fabricate(:account, username: "Matching") + followed_match = Fabricate(:account, username: "Matcher") + Fabricate(:follow, account: account, target_account: followed_match) + + results = Account.advanced_search_for("match", account) + expect(results).to eq [followed_match, match] + expect(results.first.rank).to be > results.last.rank + end + end + describe '.find_local' do before do Fabricate(:account, username: 'Alice') diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 360bbc16d..7a5b8ec89 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -12,4 +12,15 @@ RSpec.describe Tag, type: :model do expect(subject.match('https://en.wikipedia.org/wiki/Ghostbusters_(song)#Lawsuit')).to be_nil end end + + describe '.search_for' do + it 'finds tag records with matching names' do + tag = Fabricate(:tag, name: "match") + _miss_tag = Fabricate(:tag, name: "miss") + + results = Tag.search_for("match") + + expect(results).to eq [tag] + end + end end |