@ -29,37 +29,71 @@
require 'rack/utils'
class WorkPackages :: AutoCompletesController < ApplicationController
class WorkPackages :: AutoCompletesController < :: ApplicationController
before_filter :on_no_valid_scope_404
def index
@work_packages = work_package_with_id | work_packages_by_subject_or_id
respond_to do | format |
format . html do render layout : false end
format . any ( :xml , :json ) { render request . format . to_sym = > wp_hashes_with_string ( @work_packages ) }
end
end
private
def on_no_valid_scope_404
scope = determine_scope
if scope . nil?
render_404
return
return false
end
end
def work_package_with_id
scope = determine_scope
query_term = params [ :q ] . to_s
@work_packages = [ ]
# query for exact ID matches first, to make an exact match the first result of autocompletion
if query_term =~ / \ A \ d+ \ z /
@work_packages |= scope . visible . where ( id : query_term . to_i )
scope . visible . where ( id : query_term . to_i )
else
[ ]
end
end
sql_query = [ " LOWER( #{ WorkPackage . table_name } .subject) LIKE :q OR
def work_packages_by_subject_or_id
scope = determine_scope
query_term = params [ :q ] . to_s
if query_term =~ / \ A \ d+ \ z /
sql_query = [ " #{ WorkPackage . table_name } .subject LIKE :q OR
CAST ( #{WorkPackage.table_name}.id AS CHAR(13)) LIKE :q",
{ q : " % #{ query_term } % " } ]
else
sql_query = [ " LOWER( #{ WorkPackage . table_name } .subject) LIKE :q " ,
{ q : " % #{ query_term . downcase } % " } ]
end
# The filter on subject in combination with the ORDER BY on id
# seems to trip MySql's usage of indexes on the order statement
# I haven't seen similar problems on postgresql but there might be as the
# data at hand was not very large.
#
# For MySql we are therefore helping the DB optimizer to use the correct index
if ActiveRecord :: Base . connection_config [ :adapter ] == 'mysql2'
scope = scope . from ( " #{ WorkPackage . table_name } USE INDEX(PRIMARY) " )
end
@work_packages |= scope . visible
scope
. visible
. where ( sql_query )
. order ( " #{ WorkPackage . table_name } .id ASC " ) # :id does not work because...
. limit ( 10 )
respond_to do | format |
format . html do render layout : false end
format . any ( :xml , :json ) { render request . format . to_sym = > wp_hashes_with_string ( @work_packages ) }
. includes ( :type )
end
end
private
def wp_hashes_with_string ( work_packages )
work_packages . map do | work_package |
@ -77,6 +111,7 @@ class WorkPackages::AutoCompletesController < ApplicationController
end
def determine_scope
@scope || = begin
project = find_project
if params [ :scope ] == 'relatable'
@ -89,4 +124,5 @@ class WorkPackages::AutoCompletesController < ApplicationController
project . work_packages
end
end
end
end