metamaps--metamaps/app/controllers/search_controller.rb
2016-11-07 14:58:53 -05:00

163 lines
4.8 KiB
Ruby

# frozen_string_literal: true
class SearchController < ApplicationController
include TopicsHelper
include MapsHelper
include UsersHelper
include SynapsesHelper
before_action :authorize_search
after_action :verify_authorized
after_action :verify_policy_scoped, only: [:maps, :mappers, :synapses, :topics]
# get /search/topics?term=SOMETERM
def topics
term = params[:term]
user = params[:user] ? params[:user] : false
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?
# remove "topic:" if appended at beginning
term = term[6..-1] if term.downcase[0..5] == 'topic:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
# if link: search link instead
link = false
if term.downcase[0..4] == 'link:'
term = term[5..-1]
link = true
end
# check whether there's a filter by metacode as part of the query
filterByMetacode = false
Metacode.all.each do |m|
lOne = m.name.length + 1
lTwo = m.name.length
if term.downcase[0..lTwo] == m.name.downcase + ':'
term = term[lOne..-1]
filterByMetacode = m
end
end
search = '%' + term.downcase.strip + '%'
builder = policy_scope(Topic)
if filterByMetacode
if term == ''
builder = builder.none
else
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
builder = builder.where(metacode_id: filterByMetacode.id)
end
elsif desc
builder = builder.where('LOWER("desc") like ?', search)
elsif link
builder = builder.where('LOWER("link") like ?', search)
else # regular case, just search the name
builder = builder.where('LOWER("name") like ? OR
LOWER("desc") like ? OR
LOWER("link") like ?', search, search, search)
end
builder = builder.where(user: user) if user
@topics = builder.order(:name)
else
@topics = []
end
render json: autocomplete_array_json(@topics).to_json
end
# get /search/maps?term=SOMETERM
def maps
term = params[:term]
user = params[:user] ? params[:user] : nil
if term && !term.empty? && term.downcase[0..5] != 'topic:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero?
# remove "map:" if appended at beginning
term = term[4..-1] if term.downcase[0..3] == 'map:'
# if desc: search desc instead
desc = false
if term.downcase[0..4] == 'desc:'
term = term[5..-1]
desc = true
end
search = '%' + term.downcase.strip + '%'
builder = policy_scope(Map)
builder = if desc
builder.where('LOWER("desc") like ?', search)
else
builder.where('LOWER("name") like ?', search)
end
builder = builder.where(user: user) if user
@maps = builder.order(:name)
else
@maps = []
end
render json: autocomplete_map_array_json(@maps).to_json
end
# get /search/mappers?term=SOMETERM
def mappers
term = params[:term]
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?
# remove "mapper:" if appended at beginning
term = term[7..-1] if term.downcase[0..6] == 'mapper:'
search = term.downcase.strip + '%'
skip_policy_scope # TODO: builder = policy_scope(User)
builder = User.where('LOWER("name") like ?', search)
@mappers = builder.order(:name)
else
@mappers = []
end
render json: autocomplete_user_array_json(@mappers).to_json
end
# get /search/synapses?term=SOMETERM OR
# get /search/synapses?topic1id=SOMEID&topic2id=SOMEID
def synapses
term = params[:term]
topic1id = params[:topic1id]
topic2id = params[:topic2id]
if term && !term.empty?
@synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase.strip + '%').order('"desc"')
@synapses = @synapses.uniq(&:desc)
elsif topic1id && !topic1id.empty?
@one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
@two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
@synapses = @one + @two
@synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
else
@synapses = []
end
# limit to 5 results
@synapses = @synapses.to_a.slice(0, 5)
render json: autocomplete_synapse_array_json(@synapses).to_json
end
private
def authorize_search
authorize :Search
end
end