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 # load_and_authorize_resource
def index def index
params[:type] ||= 'all' @type = params[:type] || 'all'
case params[:type] @query = params[:query]
when 'all' Search.by_term_and_type(
find_collection('projects') @query,
find_collection('users') @type,
find_collection('groups') {:page => params[:page]}
find_collection('platforms') ).each do |k, v|
when 'projects', 'users', 'groups', 'platforms' var = :"@#{k}"
find_collection(params[:type]) instance_variable_set var, v unless instance_variable_defined?(var)
end end
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 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 .search
= form_tag search_index_path, :method => 'get' do = form_tag search_index_path, :method => 'get' do
.pic .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 = form_tag search_index_path, :method => 'get' do
.leftside= text_field_tag 'query', params[:query], :placeholder => t("layout.search.header"), :class => 'exsearch' .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, params[:type]), :class => 'sel80 cusel', :id => 'selSearch' .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' .leftside= submit_tag t("layout.search.header"), :class => 'button width100'
.both .both

View File

@ -7,4 +7,4 @@
- collection.each do |c| - collection.each do |c|
%tr %tr
%td= render type.singularize, type.singularize.to_sym => c %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') %h3= title t('layout.search.advanced')
= render 'form_advanced' = render 'form_advanced'
- if params[:type] == 'all' - if @type == 'all'
#all #all
= render 'table', :type => 'projects' = render 'table', :type => 'projects'
.both .both
@ -10,8 +10,8 @@
.left.width400 .left.width400
= render 'table', :type => 'platforms' = render 'table', :type => 'platforms'
- else - else
- collection = instance_variable_get("@#{params[:type]}") - collection = instance_variable_get("@#{@type}")
.tmargin10{:id => params[:type]}= render :collection => collection, :partial => params[:type].to_s.underscore.singularize .tmargin10{:id => @type}= render :collection => collection, :partial => @type.to_s.underscore.singularize
%br %br
= will_paginate collection = will_paginate collection
.both .both

View File

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