Skip to content

Commit

Permalink
Add support for advanced searches
Browse files Browse the repository at this point in the history
Reference to #211
  • Loading branch information
amoeba committed Oct 30, 2021
1 parent c599791 commit a70453f
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 12 deletions.
35 changes: 35 additions & 0 deletions helpers/search_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module SearchHelper
TOKEN_SEP = ":"

def self.process_search(query = "")
parts = {}

query.strip.split.each do |t|
subtokens = t.split(TOKEN_SEP)

if subtokens.length == 1
parts[:name] = /#{Regexp.escape(subtokens[0].strip)}/i
elsif subtokens.length == 2
field = subtokens[0].strip
value = subtokens[1].strip

# Try to find the type
klass = Character.fields.select { |k,v| v.options && v.options[:as] && v.options[:as].to_s == field }

# Convert to Integer if we should or otherwise turn into regex
if klass.length >= 1 && klass.first[1].options[:type] == Integer
value = value.to_i
elsif field == "gender"
value = /\A#{Regexp.escape(value)}\Z/i
else
value = /#{Regexp.escape(value)}/i
end

# Set it
parts[field.to_sym] = value
end
end

parts
end
end
4 changes: 2 additions & 2 deletions routes/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def self.registered(app)
# Deal with whether we're searching players or allegiances
if(params && params[:character])
if(params[:character].length >= 0)
criteria[:name] = /#{Regexp.escape(params[:character])}/i
criteria.merge!(SearchHelper::process_search(params[:character]))
end

@records = Character.limit(50).asc(:name).where(criteria)
elsif(params && params[:allegiance])
if(params[:allegiance].length >= 0)
Expand Down
40 changes: 40 additions & 0 deletions spec/unit/search_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require_relative '../spec_helper'

describe 'SearchHelper', :unit do
it "still works without a query" do
result = SearchHelper.process_search()

assert_equal({}, result)
end

it "filters by name for a simple query" do
result = SearchHelper.process_search("foo")

assert_equal({:name => /foo/i}, result)
end

it "can handle various fields in the query" do
result = SearchHelper.process_search("level:275")
assert_equal({:level => 275 }, result)

result = SearchHelper.process_search("level: 275")
assert_equal({:name => /275/i }, result)

result = SearchHelper.process_search(" level: 275 ")
assert_equal({:name => /275/i }, result)

result = SearchHelper.process_search("level:12")
assert_equal({:level => 12 }, result)

result = SearchHelper.process_search("level:12 rank:2")
assert_equal({:level => 12, :rank => 2}, result)

result = SearchHelper.process_search("foo:bar bazz:buzz")
assert_equal({:foo => /bar/i, :bazz => /buzz/i}, result)
end

it "doesn't use unbonded regexp for gender" do
result = SearchHelper.process_search("gender:male")
assert_equal({:gender => /\Amale\Z/i }, result)
end
end
1 change: 1 addition & 0 deletions views/_search.haml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

%input{:name => 'character', :type => 'text', :value => params[:player]}
%input{:type => 'submit'}
%span{"data-tippy-content" => haml(:_search_help), :class => "tippy"} ?
%span Allegiances
%form{:action => '/search', :method => 'get'}
Expand Down
16 changes: 16 additions & 0 deletions views/_search_help.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
%span Search defaults to filtering by character name and supports partial matching.
%br
%br
%span You may also search using a Google-like syntax following the form <code>field:value</code>, e.g., <code>level:275</code>.
%br
%br
%span The full list of special fields you can use this syntax with are:

%ul{:style => "margin-bottom: 0.25em;"}
%li name
%li server
%li race
%li gender
%li level
%li rank
%li allegiance_name
6 changes: 0 additions & 6 deletions views/index.haml
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,3 @@
%li Removed the monthly uploads chart from the front page and made the daily uploads chart wider.
%li Made the <a href="/player_counts-latest.json">latest player counts</a> API endpoint pretty-print its output.
%li Fixed long-standing but in the accounts view for where the 'birth' field wasn't working.

%script{:src=> "https://unpkg.com/@popperjs/core@2"}
%script{:src=> "https://unpkg.com/tippy.js@6"}

:javascript
tippy('[data-tippy-content]');
12 changes: 9 additions & 3 deletions views/layout.haml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
#content= yield
#footer
This website created with love by <a href="https://github.com/amoeba">Kolth</a>.
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "841aa24155424425a1a71c4f6acc0dfd"}'></script>
<!-- End Cloudflare Web Analytics -->
%script{:src=> "https://unpkg.com/@popperjs/core@2"}
%script{:src=> "https://unpkg.com/tippy.js@6"}

:javascript
tippy('[data-tippy-content]', {
allowHTML: true
});

<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "841aa24155424425a1a71c4f6acc0dfd"}'></script>
5 changes: 4 additions & 1 deletion views/search.haml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
%h2.title Search
- if @records && @records.count > 0
Found
= @records.count
= @records.count == 1 ? "result" : "results"
- if params && params[:character]
%ul
- @records.to_a.each do |r|
Expand All @@ -11,4 +14,4 @@
%li
%a{:href => "/allegiances/#{r.server}-#{r.name}"}= "#{r.name} (#{r.server})"
- else
%span No records found.
%span No records found.

0 comments on commit a70453f

Please sign in to comment.