Search engine: added a checkbox to search titles only (usefull when searching on common words).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@842 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
74ecb37be6
commit
b9cc65db61
@ -25,6 +25,7 @@ class SearchController < ApplicationController
|
|||||||
@question = params[:q] || ""
|
@question = params[:q] || ""
|
||||||
@question.strip!
|
@question.strip!
|
||||||
@all_words = params[:all_words] || (params[:submit] ? false : true)
|
@all_words = params[:all_words] || (params[:submit] ? false : true)
|
||||||
|
@titles_only = !params[:titles_only].nil?
|
||||||
|
|
||||||
offset = nil
|
offset = nil
|
||||||
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
||||||
@ -58,14 +59,17 @@ class SearchController < ApplicationController
|
|||||||
# no more than 5 tokens to search for
|
# no more than 5 tokens to search for
|
||||||
@tokens.slice! 5..-1 if @tokens.size > 5
|
@tokens.slice! 5..-1 if @tokens.size > 5
|
||||||
# strings used in sql like statement
|
# strings used in sql like statement
|
||||||
like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
|
like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
|
||||||
operator = @all_words ? " AND " : " OR "
|
|
||||||
@results = []
|
@results = []
|
||||||
limit = 10
|
limit = 10
|
||||||
if @project
|
if @project
|
||||||
@scope.each do |s|
|
@scope.each do |s|
|
||||||
@results += s.singularize.camelcase.constantize.search(like_tokens, @all_words, @project,
|
@results += s.singularize.camelcase.constantize.search(like_tokens, @project,
|
||||||
:limit => (limit+1), :offset => offset, :before => params[:previous].nil?)
|
:all_words => @all_words,
|
||||||
|
:titles_only => @titles_only,
|
||||||
|
:limit => (limit+1),
|
||||||
|
:offset => offset,
|
||||||
|
:before => params[:previous].nil?)
|
||||||
end
|
end
|
||||||
@results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
|
@results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
|
||||||
if params[:previous].nil?
|
if params[:previous].nil?
|
||||||
@ -82,6 +86,7 @@ class SearchController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
operator = @all_words ? ' AND ' : ' OR '
|
||||||
Project.with_scope(:find => {:conditions => Project.visible_by(logged_in_user)}) do
|
Project.with_scope(:find => {:conditions => Project.visible_by(logged_in_user)}) do
|
||||||
@results += Project.find(:all, :limit => limit, :conditions => [ (["(LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'projects'
|
@results += Project.find(:all, :limit => limit, :conditions => [ (["(LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'projects'
|
||||||
end
|
end
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<% form_tag({}, :method => :get) do %>
|
<% form_tag({}, :method => :get) do %>
|
||||||
<p><%= text_field_tag 'q', @question, :size => 30, :id => 'search-input' %>
|
<p><%= text_field_tag 'q', @question, :size => 60, :id => 'search-input' %>
|
||||||
<%= javascript_tag "Field.focus('search-input')" %>
|
<%= javascript_tag "Field.focus('search-input')" %>
|
||||||
|
|
||||||
<% @object_types.each do |t| %>
|
<% @object_types.each do |t| %>
|
||||||
<label><%= check_box_tag t, 1, @scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%></label>
|
<label><%= check_box_tag t, 1, @scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%></label>
|
||||||
<% end %>
|
<% end %>
|
||||||
<br />
|
<br />
|
||||||
<label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label></p>
|
<label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label>
|
||||||
|
<label><%= check_box_tag 'titles_only', 1, @titles_only %> <%= l(:label_search_titles_only) %></label>
|
||||||
|
</p>
|
||||||
<%= submit_tag l(:button_submit), :name => 'submit' %>
|
<%= submit_tag l(:button_submit), :name => 'submit' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -435,6 +435,7 @@ label_no_change_option: (No change)
|
|||||||
label_bulk_edit_selected_issues: Bulk edit selected issues
|
label_bulk_edit_selected_issues: Bulk edit selected issues
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
|
||||||
button_login: Login
|
button_login: Login
|
||||||
button_submit: Submit
|
button_submit: Submit
|
||||||
|
@ -527,3 +527,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -435,6 +435,7 @@ label_no_change_option: (Pas de changement)
|
|||||||
label_bulk_edit_selected_issues: Modifier les demandes sélectionnées
|
label_bulk_edit_selected_issues: Modifier les demandes sélectionnées
|
||||||
label_theme: Thème
|
label_theme: Thème
|
||||||
label_default: Défaut
|
label_default: Défaut
|
||||||
|
label_search_titles_only: Uniquement dans les titres
|
||||||
|
|
||||||
button_login: Connexion
|
button_login: Connexion
|
||||||
button_submit: Soumettre
|
button_submit: Soumettre
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -525,3 +525,4 @@ label_no_change_option: (変更無し)
|
|||||||
notice_failed_to_save_issues: "%d件の問題が保存できませんでした(%d件選択のうち) : %s."
|
notice_failed_to_save_issues: "%d件の問題が保存できませんでした(%d件選択のうち) : %s."
|
||||||
label_theme: テーマ
|
label_theme: テーマ
|
||||||
label_default: 既定
|
label_default: 既定
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -525,3 +525,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -524,3 +524,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -525,3 +525,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -527,3 +527,4 @@ label_no_change_option: (No change)
|
|||||||
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
notice_failed_to_save_issues: "Failed to save %d issue(s) on %d selected: %s."
|
||||||
label_theme: Theme
|
label_theme: Theme
|
||||||
label_default: Default
|
label_default: Default
|
||||||
|
label_search_titles_only: Search titles only
|
||||||
|
@ -59,24 +59,26 @@ module Redmine
|
|||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def search(tokens, all_tokens, project, options={})
|
def search(tokens, project, options={})
|
||||||
tokens = [] << tokens unless tokens.is_a?(Array)
|
tokens = [] << tokens unless tokens.is_a?(Array)
|
||||||
find_options = {:include => searchable_options[:include]}
|
find_options = {:include => searchable_options[:include]}
|
||||||
find_options[:limit] = options[:limit] if options[:limit]
|
find_options[:limit] = options[:limit] if options[:limit]
|
||||||
find_options[:order] = "#{searchable_options[:date_column]} " + (options[:before] ? 'DESC' : 'ASC')
|
find_options[:order] = "#{searchable_options[:date_column]} " + (options[:before] ? 'DESC' : 'ASC')
|
||||||
|
columns = searchable_options[:columns]
|
||||||
sql = ([ '(' + searchable_options[:columns].collect {|column| "(LOWER(#{column}) LIKE ?)"}.join(' OR ') + ')' ] * tokens.size).join(all_tokens ? ' AND ' : ' OR ')
|
columns.slice!(1..-1) if options[:titles_only]
|
||||||
|
|
||||||
|
sql = ([ '(' + columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}.join(' OR ') + ')' ] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
|
||||||
if options[:offset]
|
if options[:offset]
|
||||||
sql = "(#{sql}) AND (#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
|
sql = "(#{sql}) AND (#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
|
||||||
end
|
end
|
||||||
find_options[:conditions] = [sql, * (tokens * searchable_options[:columns].size).sort]
|
find_options[:conditions] = [sql, * (tokens * columns.size).sort]
|
||||||
|
|
||||||
results = with_scope(:find => {:conditions => ["#{searchable_options[:project_key]} = ?", project.id]}) do
|
results = with_scope(:find => {:conditions => ["#{searchable_options[:project_key]} = ?", project.id]}) do
|
||||||
find(:all, find_options)
|
find(:all, find_options)
|
||||||
end
|
end
|
||||||
if searchable_options[:with]
|
if searchable_options[:with] && !options[:titles_only]
|
||||||
searchable_options[:with].each do |model, assoc|
|
searchable_options[:with].each do |model, assoc|
|
||||||
results += model.to_s.camelcase.constantize.search(tokens, all_tokens, project, options).collect {|r| r.send assoc}
|
results += model.to_s.camelcase.constantize.search(tokens, project, options).collect {|r| r.send assoc}
|
||||||
end
|
end
|
||||||
results.uniq!
|
results.uniq!
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user