Skip to content

Commit 578b365

Browse files
committed
Add super-secret search results page
1 parent 7927099 commit 578b365

File tree

7 files changed

+93
-0
lines changed

7 files changed

+93
-0
lines changed

app/assets/javascripts/search.coffee

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Place all the behaviors and hooks related to the matching controller here.
2+
# All this logic will automatically be available in application.js.
3+
# You can use CoffeeScript in this file: http://coffeescript.org/

app/assets/stylesheets/search.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Place all the styles related to the Search controller here.
2+
// They will automatically be included in application.css.
3+
// You can use Sass (SCSS) here: http://sass-lang.com/

app/controllers/search_controller.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class SearchController < ApplicationController
2+
def results
3+
@query = params[:q]
4+
5+
@results = Hash.new([])
6+
current_user.content.each do |content_type, content_list|
7+
@results[content_type] = content_list.select { |content| search_match?(content, @query) }
8+
end
9+
end
10+
11+
private
12+
13+
# Returns whether a given piece of content matches against a given search query.
14+
# Usage: search_match?(some_character_instance, 'Bob') => true|false
15+
def search_match? content, query
16+
# We match if the query exists in any searchable fields on this content
17+
searchable_attributes_for(content.class).any? do |attribute|
18+
content_value = content.send(attribute)
19+
content_value.present? && content_value.to_s.downcase.include?(query.downcase)
20+
end
21+
end
22+
23+
# Returns all attributes on a class that we match against in a search.
24+
# Usage: searchable_attributes_for(Character) => [:name, :role, ...]
25+
def searchable_attributes_for klass
26+
related_controller = "#{klass.to_s.pluralize}Controller".constantize.new
27+
related_controller.send(:content_param_list).select do |attribute|
28+
!attribute.is_a?(Hash) && searchable_attribute?(attribute.to_s)
29+
end
30+
end
31+
32+
# Returns whether or not a particular attribute should be included on searches.
33+
# Usage: searchable_attribute?('name') => true|false
34+
def searchable_attribute? attribute
35+
!attribute.end_with?('_id') && !attribute.end_with?('_attributes') && !attribute.end_with?('_values')
36+
end
37+
end

app/helpers/search_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module SearchHelper
2+
end

app/views/search/results.html.erb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<h3>
2+
<%= @query %>
3+
<small class="grey-text">
4+
<%= pluralize @results.values.flatten.count, 'match' %>
5+
</small>
6+
</h3>
7+
8+
<ul class="collapsible popout" data-collapsible="accordion">
9+
<% @results.each do |content_type, content_list| %>
10+
<% next if content_list.empty? %>
11+
<% content_class = content_type.to_s.singularize.capitalize.constantize %>
12+
13+
<li>
14+
<div class="collapsible-header">
15+
<i class="material-icons <%= content_class.color %>-text"><%= content_class.icon %></i>
16+
<%= content_type.to_s.humanize %>
17+
<span class="grey-text"><%= pluralize content_list.count, 'result' %></span>
18+
</div>
19+
<div class="collapsible-body">
20+
<%= render partial: 'content/list/list', locals: { content_list: content_list, show_add_another_form: false } %>
21+
</div>
22+
</li>
23+
<% end %>
24+
</ul>
25+
26+
<% if @results.values.flatten.count.zero? %>
27+
<div class="card-panel">
28+
<p>
29+
Sorry, nothing matched your search query!
30+
</p>
31+
32+
<p>
33+
Think this is a bug?
34+
<%= link_to 'Please report it!', 'https://docs.google.com/forms/d/e/1FAIpQLSe0jnqJlcPJDqwogGere5j8-8F1nSGGYkzbsI-XkOeMnGwLrA/viewform' %>
35+
</p>
36+
</div>
37+
<% end %>

config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# rubocop:disable LineLength
22

33
Rails.application.routes.draw do
4+
45
devise_for :users, :controllers => { registrations: 'registrations' }
56
resources :users
67

@@ -105,6 +106,7 @@
105106
# Coming Soon TM
106107
get '/plots', to: 'main#comingsoon'
107108
end
109+
get 'search/', to: 'search#results'
108110

109111
scope 'admin' do
110112
get '/', to: 'admin#dashboard', as: :admin_dashboard
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require 'test_helper'
2+
3+
class SearchControllerTest < ActionController::TestCase
4+
test "should get results" do
5+
get :results
6+
assert_response :success
7+
end
8+
9+
end

0 commit comments

Comments
 (0)