##// END OF EJS Templates
remove trailing white-spaces from vendor/plugins/acts_as_searchable/lib/acts_as_searchable.rb...
Toshi MARUYAMA -
r9171:f800d2185e2f
parent child
Show More
@@ -1,133 +1,133
1 1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 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 def self.included(base)
21 def self.included(base)
22 22 base.extend ClassMethods
23 end
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 # Should we search custom fields on this model ?
49 49 searchable_options[:search_custom_fields] = !reflect_on_association(:custom_values).nil?
50
50
51 51 send :include, Redmine::Acts::Searchable::InstanceMethods
52 52 end
53 53 end
54 54
55 55 module InstanceMethods
56 56 def self.included(base)
57 57 base.extend ClassMethods
58 58 end
59 59
60 60 module ClassMethods
61 61 # Searches the model for the given tokens
62 62 # projects argument can be either nil (will search all projects), a project or an array of projects
63 63 # Returns the results and the results count
64 64 def search(tokens, projects=nil, options={})
65 65 if projects.is_a?(Array) && projects.empty?
66 66 # no results
67 67 return [[], 0]
68 68 end
69 69
70 70 # TODO: make user an argument
71 71 user = User.current
72 72 tokens = [] << tokens unless tokens.is_a?(Array)
73 73 projects = [] << projects unless projects.nil? || projects.is_a?(Array)
74
74
75 75 find_options = {:include => searchable_options[:include]}
76 76 find_options[:order] = "#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')
77
77
78 78 limit_options = {}
79 79 limit_options[:limit] = options[:limit] if options[:limit]
80 80 if options[:offset]
81 81 limit_options[:conditions] = "(#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
82 82 end
83
83
84 84 columns = searchable_options[:columns]
85 85 columns = columns[0..0] if options[:titles_only]
86
86
87 87 token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
88
88
89 89 if !options[:titles_only] && searchable_options[:search_custom_fields]
90 90 searchable_custom_field_ids = CustomField.find(:all,
91 91 :select => 'id',
92 92 :conditions => { :type => "#{self.name}CustomField",
93 93 :searchable => true }).collect(&:id)
94 94 if searchable_custom_field_ids.any?
95 95 custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
96 96 " WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
97 97 " AND #{CustomValue.table_name}.custom_field_id IN (#{searchable_custom_field_ids.join(',')}))"
98 98 token_clauses << custom_field_sql
99 99 end
100 100 end
101
101
102 102 sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
103
103
104 104 find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
105
105
106 106 scope = self
107 107 project_conditions = []
108 108 if searchable_options.has_key?(:permission)
109 109 project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project)
110 110 elsif respond_to?(:visible)
111 111 scope = scope.visible(user)
112 112 else
113 113 ActiveSupport::Deprecation.warn "acts_as_searchable with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
114 114 project_conditions << Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym)
115 115 end
116 116 # TODO: use visible scope options instead
117 117 project_conditions << "#{searchable_options[:project_key]} IN (#{projects.collect(&:id).join(',')})" unless projects.nil?
118 118 project_conditions = project_conditions.empty? ? nil : project_conditions.join(' AND ')
119
119
120 120 results = []
121 121 results_count = 0
122 122
123 123 scope = scope.scoped({:conditions => project_conditions}).scoped(find_options)
124 124 results_count = scope.count(:all)
125 125 results = scope.find(:all, limit_options)
126 126
127 127 [results, results_count]
128 128 end
129 129 end
130 130 end
131 131 end
132 132 end
133 133 end
General Comments 0
You need to be logged in to leave comments. Login now