diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index 0a5ccb68..f89b6b78 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -1,172 +1,20 @@ # frozen_string_literal: true class MainController < ApplicationController - include TopicsHelper - include MapsHelper - include UsersHelper - include SynapsesHelper + after_action :verify_authorized + after_action :verify_policy_scoped, only: [:home] - after_action :verify_policy_scoped, except: [:requestinvite, :searchmappers] - - respond_to :html, :json - - # home page + # GET / def home - @maps = policy_scope(Map).order('updated_at DESC').page(1).per(20) + authorize :Main respond_to do |format| format.html do if !authenticated? render 'main/home' else + @maps = policy_scope(Map).order(updated_at: :desc).page(1).per(20) render 'explore/active' end end end end - - ### SEARCHING ### - - # get /search/topics?term=SOMETERM - def searchtopics - 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 + '%' - 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) - end - - # get /search/maps?term=SOMETERM - def searchmaps - 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 + '%' - 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) - end - - # get /search/mappers?term=SOMETERM - def searchmappers - 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 + '%' - - 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) - end - - # get /search/synapses?term=SOMETERM OR - # get /search/synapses?topic1id=SOMEID&topic2id=SOMEID - def searchsynapses - term = params[:term] - topic1id = params[:topic1id] - topic2id = params[:topic2id] - - if term && !term.empty? - @synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase + '%').order('"desc"') - - @synapses = @synapses.uniq(&:desc) - elsif topic1id && !topic1id.empty? - @one = policy_scope(Synapse).where('topic1_id = ? AND topic2_id = ?', topic1id, topic2id) - @two = policy_scope(Synapse).where('topic2_id = ? AND topic1_id = ?', topic1id, 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) - end end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb new file mode 100644 index 00000000..91b0b44d --- /dev/null +++ b/app/controllers/search_controller.rb @@ -0,0 +1,162 @@ +# frozen_string_literal: true +class MainController < 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 + '%' + 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) + 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 + '%' + 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) + 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 + '%' + + 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) + 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 + '%').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) + end + + private + + def authorize_search + authorize :Search + end +end diff --git a/app/policies/main_policy.rb b/app/policies/main_policy.rb index e0ffc30b..1c7a00e5 100644 --- a/app/policies/main_policy.rb +++ b/app/policies/main_policy.rb @@ -1,27 +1,6 @@ # frozen_string_literal: true class MainPolicy < ApplicationPolicy - def initialize(user, _record) - @user = user - @record = nil - end - def home? true end - - def searchtopics? - true - end - - def searchmaps? - true - end - - def searchmappers? - true - end - - def searchsynapses? - true - end end diff --git a/app/policies/search_policy.rb b/app/policies/search_policy.rb new file mode 100644 index 00000000..5b783457 --- /dev/null +++ b/app/policies/search_policy.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +class SearchPolicy < ApplicationPolicy + def topics? + true + end + + def maps? + true + end + + def mappers? + true + end + + def synapses? + true + end +end diff --git a/config/routes.rb b/config/routes.rb index b114d3d6..4800780d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,10 +5,12 @@ Metamaps::Application.routes.draw do get 'request', to: 'main#requestinvite', as: :request - get 'search/topics', to: 'main#searchtopics', as: :searchtopics - get 'search/maps', to: 'main#searchmaps', as: :searchmaps - get 'search/mappers', to: 'main#searchmappers', as: :searchmappers - get 'search/synapses', to: 'main#searchsynapses', as: :searchsynapses + namespace :search do + get :topics + get :maps + get :mappers + get :synapses + end namespace :api, path: '/api', default: { format: :json } do namespace :v2, path: '/v2' do