Merge pull request #734 from warpc/731-search-api

[refs #731]: Search api
This commit is contained in:
Vladimir Sharshov 2012-11-21 07:22:14 -08:00
commit 22b7ba5bd5
15 changed files with 110 additions and 23 deletions

View File

@ -0,0 +1,12 @@
# -*- encoding : utf-8 -*-
class Api::V1::SearchController < Api::V1::BaseController
before_filter :authenticate_user! unless APP_CONFIG['anonymous_access']
def index
@results = Search.by_term_and_type(
params[:query],
(params[:type] || 'all'),
paginate_params
)
end
end

View File

@ -4,22 +4,15 @@ class SearchController < ApplicationController
# load_and_authorize_resource
def index
params[:type] ||= 'all'
case params[:type]
when 'all'
find_collection('projects')
find_collection('users')
find_collection('groups')
find_collection('platforms')
when 'projects', 'users', 'groups', 'platforms'
find_collection(params[:type])
@type = params[:type] || 'all'
@query = params[:query]
Search.by_term_and_type(
@query,
@type,
{:page => params[:page]}
).each do |k, v|
var = :"@#{k}"
instance_variable_set var, v unless instance_variable_defined?(var)
end
end
protected
def find_collection(type)
var = :"@#{type}"
instance_variable_set var, type.classify.constantize.opened.search(params[:query]).search_order.paginate(:page => params[:page]) unless instance_variable_defined?(var)
end
end

26
app/models/search.rb Normal file
View File

@ -0,0 +1,26 @@
# -*- encoding : utf-8 -*-
class Search
TYPES = ['projects', 'users', 'groups', 'platforms']
def self.by_term_and_type(term, type, paginate_params)
results = {}
case type
when 'all'
TYPES.each{ |t| results[t] = find_collection(t, term, paginate_params) }
when *TYPES
results[type] = find_collection(type, term, paginate_params)
end
results
end
class << self
protected
def find_collection(type, term, paginate_params)
type.classify.constantize.opened.
search(term).
search_order.
paginate(paginate_params)
end
end
end

View File

@ -0,0 +1,3 @@
json.groups results do |group|
json.partial! 'member', :member => group, :json => json
end

View File

@ -0,0 +1,3 @@
json.(member, :id, :uname)
json.(member, :name) if member.is_a?(User)
json.url member_path(member)

View File

@ -0,0 +1,3 @@
json.platforms results do |platform|
json.partial! 'api/v1/platforms/platform', :platform => platform, :json => json
end

View File

@ -0,0 +1,3 @@
json.projects results do |project|
json.partial! 'api/v1/projects/project', :project => project, :json => json
end

View File

@ -0,0 +1,3 @@
json.users results do |user|
json.partial! 'member', :member => user, :json => json
end

View File

@ -0,0 +1,6 @@
json.results do |json|
@results.each do |tag, results|
json.partial! tag.dup, :results => results, :json => json
end
end
json.url api_v1_search_index_path(:format => :json)

View File

@ -1,4 +1,4 @@
.search
= form_tag search_index_path, :method => 'get' do
.pic
.field= text_field_tag 'query', params[:query], :placeholder => t("layout.search.header")
.field= text_field_tag 'query', @query, :placeholder => t("layout.search.header")

View File

@ -1,5 +1,5 @@
= form_tag search_index_path, :method => 'get' do
.leftside= text_field_tag 'query', params[:query], :placeholder => t("layout.search.header"), :class => 'exsearch'
.lineForm.leftside.rmargin10= select_tag 'type', options_for_select(t('layout.search.types').invert, params[:type]), :class => 'sel80 cusel', :id => 'selSearch'
.leftside= text_field_tag 'query', @query, :placeholder => t("layout.search.header"), :class => 'exsearch'
.lineForm.leftside.rmargin10= select_tag 'type', options_for_select(t('layout.search.types').invert, @type), :class => 'sel80 cusel', :id => 'selSearch'
.leftside= submit_tag t("layout.search.header"), :class => 'button width100'
.both

View File

@ -7,4 +7,4 @@
- collection.each do |c|
%tr
%td= render type.singularize, type.singularize.to_sym => c
= link_to t('layout.search.all'), search_index_path(:query => params[:query], :type => type) if collection.present?
= link_to t('layout.search.all'), search_index_path(:query => @query, :type => type) if collection.present?

View File

@ -1,6 +1,6 @@
%h3= title t('layout.search.advanced')
= render 'form_advanced'
- if params[:type] == 'all'
- if @type == 'all'
#all
= render 'table', :type => 'projects'
.both
@ -10,8 +10,8 @@
.left.width400
= render 'table', :type => 'platforms'
- else
- collection = instance_variable_get("@#{params[:type]}")
.tmargin10{:id => params[:type]}= render :collection => collection, :partial => params[:type].to_s.underscore.singularize
- collection = instance_variable_get("@#{@type}")
.tmargin10{:id => @type}= render :collection => collection, :partial => @type.to_s.underscore.singularize
%br
= will_paginate collection
.both

View File

@ -13,6 +13,7 @@ Rosa::Application.routes.draw do
namespace :api do
namespace :v1 do
resources :advisories, :only => [:index, :show, :create, :update]
resources :search, :only => [:index]
resources :build_lists, :only => [:index, :create, :show] do
member {
get :publish

View File

@ -0,0 +1,34 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
shared_examples_for 'able search with api' do
it 'should be able to search' do
get :index, :format => :json
response.should be_success
response.should render_template(:index)
end
end
shared_examples_for 'not able search with api' do
it 'should not be able to search' do
get :index, :format => :json
response.should redirect_to(controller.current_user ? forbidden_path : new_user_session_path)
end
end
describe Api::V1::SearchController do
before { stub_symlink_methods }
context 'as guest' do
if APP_CONFIG['anonymous_access']
it_should_behave_like 'able search with api'
else
it_should_behave_like 'not able search with api'
end
end
context 'as user' do
before {set_session_for FactoryGirl.create(:user)}
it_should_behave_like 'able search with api'
end
end