fairplaysk/datacamp

View on GitHub
app/controllers/searches_controller.rb

Summary

Maintainability
A
25 mins
Test Coverage
class SearchesController < ApplicationController

  ########################################################################
  # Search/Create -> Creates new search spicified by one of the following
  # parameters:
  # 1. query_string -> global search for one string. This way only 5 results
  #                    from each dataset are loaded. After search user is redi-
  #                    rected to search/show with results.
  # 2. predicates   -> dataset-wide search specified by predicates array. This
  #                    search will include all results from a dataset. User
  # =>                 will be redirected back to dataset/view.

  def create
    search_params = params[:search] || {}
    if search_params[:predicates]
      query = SearchQuery.query_with_predicates(create_predicates_from_hash(search_params[:predicates]), :scope => "dataset", :object => search_params[:dataset])
      search = Search.create(:query => query, :search_type => 'predicates', :session => @current_session)

      if search_params[:dataset].present?
        redirect_to dataset_path(DatasetDescription.find_by_identifier(search.query.object), :search_id => search.id)
      else
        redirect_to search_path(search)
      end
    else
      redirect_to datasets_path, :notice => 'Something went wrong...'
    end
  end

  def predicate_rows
    @dataset_description = DatasetDescription.find_by_identifier(params[:identifier])
    render :predicate_rows, layout: false
  end

  ########################################################################
  # Quick search using Sphinx. If Sphinx search engine couldn't be used
  # redirect to regular search.
  def quick
    search = Search.build_from_query_string(params[:query_string])
    search.save
    redirect_to search
  end

  def show
    @search = Search.find(params[:id])
    dds = DatasetDescription

    dds = dds.where(category_id: params[:category_id]) if params[:category_id] # TODO: test filter by category_id

    descriptions = dds.joins(:category).order('dataset_categories.position, dataset_descriptions.position').active
    datasets = descriptions.map(&:dataset_model)
    searches = SearchEngine.new.search(datasets, @search)
    @query_string = @search.query_string

    @results = {}
    descriptions.includes([
        {:relations => :relationship_dataset_description},
        :derived_field_descriptions,
        :field_descriptions_for_detail,
        {:field_descriptions_for_search => [:translations, :data_format] }]
    ).zip(searches).each do |dataset_description, matches|
      if matches.any?
        @results[dataset_description.category] ||= {}
        @results[dataset_description.category][dataset_description] = matches
      end
    end
  end

  protected

  def create_predicates_from_hash(hash)
    hash.collect { |predicate|
      if predicate[:operator].present? && predicate[:value].present?
        SearchPredicate.create({:scope => "record", :search_field => predicate[:field], :operator => predicate[:operator], :argument => predicate[:value]})
      end
    }.select { |p| p.present? }
  end
end