From a71f5e26e057555056a8c6e41e544f3478d63f1c Mon Sep 17 00:00:00 2001 From: Israel Barreto Sant'Anna <ibsa14@inf.ufpr.br> Date: Thu, 14 Apr 2016 09:31:52 -0300 Subject: [PATCH] SearchController for REST API created and logic migrated to SearchService class Signed-off-by: Israel Barreto Sant'Anna <ibsa14@inf.ufpr.br> --- app/controllers/v1/search_controller.rb | 21 +++++ app/services/search_service.rb | 119 ++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 app/controllers/v1/search_controller.rb create mode 100644 app/services/search_service.rb diff --git a/app/controllers/v1/search_controller.rb b/app/controllers/v1/search_controller.rb new file mode 100644 index 00000000..7ed1ead4 --- /dev/null +++ b/app/controllers/v1/search_controller.rb @@ -0,0 +1,21 @@ +class V1::SearchController < ApplicationController + + # GET v1/searches + # GET v1/searches.json + def index + render json: search_service.search(params) + end + + # GET v1/searches/autocomplete + # GET v1/searches/autocomplete.json + def autocomplete + render json: search_service.autocomplete(params) + end + + private + + def search_service + @search_service ||= SearchService.new + end + +end \ No newline at end of file diff --git a/app/services/search_service.rb b/app/services/search_service.rb new file mode 100644 index 00000000..8ee8fdd9 --- /dev/null +++ b/app/services/search_service.rb @@ -0,0 +1,119 @@ +class SearchService + + def search(params) + params[:query] = "*" if params[:query].blank? + + case params[:search_class] + when "LearningObject" + result = LearningObject.search params[:query], where: where_hash(params), order: lo_order_hash(params[:order]), page: params[:page] || 1, per_page: 10 + when "Collection" + result = Collection.search params[:query], where: {privacy: "public"}, order: col_order_hash(params[:order]), page: params[:page] || 1, per_page: 10 + when "User" + result = User.search params[:query], order: user_order_hash(params[:order]), page: params[:page] || 1, per_page: 10 + else + raise "Wrong search class parameter" + end + result + end + + def autocomplete(params) + params_hash = {} + get_thumbnail = nil + case params[:search_class] + when "LearningObject" + params_hash = { fields: ['name^10', 'description', 'author'] } + get_thumbnail = Proc.new { |obj| image_tag(learning_object_thumbnail(obj)) } + when "Collection" + params_hash = { where: {privacy: "public"}, + fields: ['name^10', 'description', 'owner'] } + get_thumbnail = Proc.new { |obj| image_tag("/assets/icons/collection") } + when "User" + params_hash = { fields: ['name'] } + get_thumbnail = Proc.new { |obj| image_tag(obj.avatar.url(:thumb), 32) } + else + raise "Wrong search class parameter" + end + autocomplete_search(Object.const_get(params[:search_class]), params[:query], params_hash, get_thumbnail) + end + + private + + def autocomplete_search(search_class, query, params_hash={}, get_thumbnail) + response = [] + search_params = { limit: 10, misspellings: { below: 5 }, where: {state: validate_object} } + objs = search_class.search(query, search_params.merge(params_hash)) + objs.each do |obj| + hash = {} + hash["name"] = obj.name + hash["thumbnail"] = get_thumbnail.call(obj) + hash["url"] = url_for([obj, :only_path => false]) + response << hash + end + response + end + + def image_tag(image, width=56, height=32) + ActionController::Base.helpers.image_tag image, width: width, height: height, class: "autocomplete" + end + + def where_hash(params) + hash = {} + + topics = params[:topic] unless params[:topic].blank? + topics += ", " unless topics.nil? + topics = topics.to_s + params[:school_level] unless params[:school_level].blank? + + # build hash + hash[:topics_name] = topics.split(', ') unless topics.nil? + hash[:object_type] = params[:type].split(', ') unless params[:type].blank? + hash[:publisher] = params[:source].split("-s- ") unless params[:source].blank? + hash[:state] = validate_object + # year = params[:year].blank? ? nil : params[:year].split('-').take(2) + + hash.blank? ? nil : hash + end + + def lo_order_hash(order) + case order + when 'author' + { author: {order: :asc, unmapped_type: :string} } + when 'publicationasc' + { published_at: {order: :asc, unmapped_type: :timestamp} } + when 'publicationdesc' + { published_at: {order: :desc, unmapped_type: :timestamp} } + when 'title' + { name: {order: :asc, unmapped_type: :string} } + else + { score: {order: :desc, unmapped_type: :integer} } + end + end + + def col_order_hash(order) + case order + when 'author' + { owner: {order: :asc, unmapped_type: :string} } + when 'publicationasc' + { created_at: {order: :asc, unmapped_type: :timestamp} } + when 'publicationdesc' + { created_at: {order: :desc, unmapped_type: :timestamp} } + when 'title' + { name: {order: :asc, unmapped_type: :string} } + else + { score: {order: :desc, unmapped_type: :integer} } + end + end + + def user_order_hash(order) + if order == 'title' + { name: {order: :asc, unmapped_type: :string} } + else + { score: {order: :desc, unmapped_type: :integer} } + end + end + + def validate_object + return 'published' if current_user.nil? || !current_user.is_admin? + return ['published', 'suspended', 'draft'] + end + +end \ No newline at end of file -- GitLab