diff --git a/app/assets/javascripts/questions.js b/app/assets/javascripts/questions.js index dee720f..969b275 100644 --- a/app/assets/javascripts/questions.js +++ b/app/assets/javascripts/questions.js @@ -1,2 +1,14 @@ // Place all the behaviors and hooks related to the matching controller here. // All this logic will automatically be available in application.js. + + +$(document).ready(function() { + $('.select2').select2({ + ajax: { + url: '/search', + dataType: 'json' + }, + minimumInputLength: 3, + width: '200px' + }); +}); diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js new file mode 100644 index 0000000..dee720f --- /dev/null +++ b/app/assets/javascripts/search.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/search.scss b/app/assets/stylesheets/search.scss new file mode 100644 index 0000000..22fd394 --- /dev/null +++ b/app/assets/stylesheets/search.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the search controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb new file mode 100644 index 0000000..df3eedf --- /dev/null +++ b/app/controllers/search_controller.rb @@ -0,0 +1,7 @@ +class SearchController < ApplicationController + def index + result = ContestSearch.search(params[:q]).limit(4) + hash_results = result.map {|r| {id: r.id, text: r.display_name} } + render json: { "results": hash_results } + end +end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb new file mode 100644 index 0000000..b3ce20a --- /dev/null +++ b/app/helpers/search_helper.rb @@ -0,0 +1,2 @@ +module SearchHelper +end diff --git a/app/models/candidate.rb b/app/models/candidate.rb index 207c094..61651ad 100644 --- a/app/models/candidate.rb +++ b/app/models/candidate.rb @@ -1,3 +1,7 @@ class Candidate < ApplicationRecord belongs_to :contest + + def display_name + primary_name + end end diff --git a/app/models/contest.rb b/app/models/contest.rb index 375afc5..0a2a92f 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -1,2 +1,6 @@ class Contest < ApplicationRecord + + def display_name + "#{name} - #{electoral_district_name}" + end end diff --git a/app/models/contest_search.rb b/app/models/contest_search.rb new file mode 100644 index 0000000..5435476 --- /dev/null +++ b/app/models/contest_search.rb @@ -0,0 +1,23 @@ +class ContestSearch + def self.search(query) + columns = %w(primary_office_name secondary_office_name electoral_district_name) + tsvector = to_tsvector(columns) + results = Contest.where("to_tsvector(#{tsvector}) @@ to_tsquery('english', ?)", to_tsquery(query)) + + if results.empty? + columns = %w(primary_name primary_party secondary_name) + tsvector = to_tsvector(columns) + results = Candidate.where("to_tsvector(#{tsvector}) @@ to_tsquery('english', ?)", to_tsquery(query)) + end + + results + end + + def self.to_tsvector(columns) + columns.map {|c| "coalesce(#{c}, '')" }.join(" || ' ' || ") + end + + def self.to_tsquery(query) + res = query.split(' ').map {|q| "#{q}:*" }.join(" & ") + end +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index a4fa2a6..70090b3 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,6 +11,8 @@ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + +
diff --git a/app/views/questions/_question.html.erb b/app/views/questions/_question.html.erb index e35c9ed..e45e47e 100644 --- a/app/views/questions/_question.html.erb +++ b/app/views/questions/_question.html.erb @@ -9,7 +9,7 @@