##// END OF EJS Templates
Fixed: 'search titles only' box ignored after one search is done on titles only....
Jean-Philippe Lang -
r1667:aaca2c50e563
parent child
Show More
@@ -1,122 +1,122
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module Redmine
19 19 module Acts
20 20 module Searchable
21 21 def self.included(base)
22 22 base.extend ClassMethods
23 23 end
24 24
25 25 module ClassMethods
26 26 # Options:
27 27 # * :columns - a column or an array of columns to search
28 28 # * :project_key - project foreign key (default to project_id)
29 29 # * :date_column - name of the datetime column (default to created_on)
30 30 # * :sort_order - name of the column used to sort results (default to :date_column or created_on)
31 31 # * :permission - permission required to search the model (default to :view_"objects")
32 32 def acts_as_searchable(options = {})
33 33 return if self.included_modules.include?(Redmine::Acts::Searchable::InstanceMethods)
34 34
35 35 cattr_accessor :searchable_options
36 36 self.searchable_options = options
37 37
38 38 if searchable_options[:columns].nil?
39 39 raise 'No searchable column defined.'
40 40 elsif !searchable_options[:columns].is_a?(Array)
41 41 searchable_options[:columns] = [] << searchable_options[:columns]
42 42 end
43 43
44 44 searchable_options[:project_key] ||= "#{table_name}.project_id"
45 45 searchable_options[:date_column] ||= "#{table_name}.created_on"
46 46 searchable_options[:order_column] ||= searchable_options[:date_column]
47 47
48 48 # Permission needed to search this model
49 49 searchable_options[:permission] = "view_#{self.name.underscore.pluralize}".to_sym unless searchable_options.has_key?(:permission)
50 50
51 51 # Should we search custom fields on this model ?
52 52 searchable_options[:search_custom_fields] = !reflect_on_association(:custom_values).nil?
53 53
54 54 send :include, Redmine::Acts::Searchable::InstanceMethods
55 55 end
56 56 end
57 57
58 58 module InstanceMethods
59 59 def self.included(base)
60 60 base.extend ClassMethods
61 61 end
62 62
63 63 module ClassMethods
64 64 # Searches the model for the given tokens
65 65 # projects argument can be either nil (will search all projects), a project or an array of projects
66 66 # Returns the results and the results count
67 67 def search(tokens, projects=nil, options={})
68 68 tokens = [] << tokens unless tokens.is_a?(Array)
69 69 projects = [] << projects unless projects.nil? || projects.is_a?(Array)
70 70
71 71 find_options = {:include => searchable_options[:include]}
72 72 find_options[:order] = "#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')
73 73
74 74 limit_options = {}
75 75 limit_options[:limit] = options[:limit] if options[:limit]
76 76 if options[:offset]
77 77 limit_options[:conditions] = "(#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
78 78 end
79 79
80 80 columns = searchable_options[:columns]
81 columns.slice!(1..-1) if options[:titles_only]
81 columns = columns[0..0] if options[:titles_only]
82 82
83 83 token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
84 84
85 85 if !options[:titles_only] && searchable_options[:search_custom_fields]
86 86 searchable_custom_field_ids = CustomField.find(:all,
87 87 :select => 'id',
88 88 :conditions => { :type => "#{self.name}CustomField",
89 89 :searchable => true }).collect(&:id)
90 90 if searchable_custom_field_ids.any?
91 91 custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
92 92 " WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
93 93 " AND #{CustomValue.table_name}.custom_field_id IN (#{searchable_custom_field_ids.join(',')}))"
94 94 token_clauses << custom_field_sql
95 95 end
96 96 end
97 97
98 98 sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
99 99
100 100 find_options[:conditions] = [sql, * (tokens * token_clauses.size).sort]
101 101
102 102 project_conditions = []
103 103 project_conditions << (searchable_options[:permission].nil? ? Project.visible_by(User.current) :
104 104 Project.allowed_to_condition(User.current, searchable_options[:permission]))
105 105 project_conditions << "#{searchable_options[:project_key]} IN (#{projects.collect(&:id).join(',')})" unless projects.nil?
106 106
107 107 results = []
108 108 results_count = 0
109 109
110 110 with_scope(:find => {:conditions => project_conditions.join(' AND ')}) do
111 111 with_scope(:find => find_options) do
112 112 results_count = count(:all)
113 113 results = find(:all, limit_options)
114 114 end
115 115 end
116 116 [results, results_count]
117 117 end
118 118 end
119 119 end
120 120 end
121 121 end
122 122 end
General Comments 0
You need to be logged in to leave comments. Login now