Project

General

Profile

Patch #821 » search_all_projects_one_query.patch

Peter Van den Bosch, 2008-05-17 01:53

View differences:

app/controllers/search_controller.rb (working copy)
28 28
    @question.strip!
29 29
    @all_words = params[:all_words] || (params[:submit] ? false : true)
30 30
    @titles_only = !params[:titles_only].nil?
31
    @all_projects = !@project || !params[:all_projects].nil?
31 32
    
32 33
    offset = nil
33 34
    begin; offset = params[:offset].to_time if params[:offset]; rescue; end
......
38 39
      return
39 40
    end
40 41
    
41
    if @project
42
      # only show what the user is allowed to view
43
      @object_types = %w(issues news documents changesets wiki_pages messages)
44
      @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)}
45
      
46
      @scope = @object_types.select {|t| params[t]}
47
      @scope = @object_types if @scope.empty?
42
    @object_types = %w(issues news documents changesets wiki_pages messages)    
43

  
44
    # only show what the user is allowed to view
45
    if !@all_projects
46
      @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)}    
48 47
    else
49
      @object_types = @scope = %w(projects)
48
      @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, nil, {:global => true})}
50 49
    end
51 50
    
51
    #allow searching for projects when not inside one
52
    if !@project
53
      @object_types << "projects"
54
    end
55

  
56
    @scope = @object_types.select {|t| params[t]}
57
    @scope = @object_types if @scope.empty?
58
    
52 59
    # extract tokens from the question
53 60
    # eg. hello "bye bye" => ["hello", "bye bye"]
54 61
    @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
......
62 69
      like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}      
63 70
      @results = []
64 71
      limit = 10
65
      if @project        
66
        @scope.each do |s|
67
          @results += s.singularize.camelcase.constantize.search(like_tokens, @project,
68
            :all_words => @all_words,
69
            :titles_only => @titles_only,
70
            :limit => (limit+1),
71
            :offset => offset,
72
            :before => params[:previous].nil?)
72

  
73
      @scope.each do |s|
74
        
75
        if @all_projects
76
          projects_to_search = Project.find :all
77
          projects_to_search.select {|p| User.current.allowed_to?("view_#{s}".to_sym, p)}
78
        else
79
          projects_to_search = @project
73 80
        end
74
        @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
75
        if params[:previous].nil?
76
          @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
77
          if @results.size > limit
78
            @pagination_next_date = @results[limit-1].event_datetime 
79
            @results = @results[0, limit]
80
          end
81
        else
82
          @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
83
          if @results.size > limit
84
            @pagination_previous_date = @results[-(limit)].event_datetime 
85
            @results = @results[-(limit), limit]
86
          end
81
        
82
        @results += s.singularize.camelcase.constantize.search(like_tokens, projects_to_search,
83
          :all_words => @all_words,
84
          :titles_only => @titles_only,
85
          :limit => (limit+1),
86
          :offset => offset,
87
          :before => params[:previous].nil?)
88
      end
89
      @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
90
      if params[:previous].nil?
91
        @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
92
        if @results.size > limit
93
          @pagination_next_date = @results[limit-1].event_datetime 
94
          @results = @results[0, limit]
87 95
        end
88 96
      else
89
        operator = @all_words ? ' AND ' : ' OR '
90
        @results += Project.find(:all, 
91
                                 :limit => limit,
92
                                 :conditions => [ (["(#{Project.visible_by(User.current)}) AND (LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort]
93
                                 ) if @scope.include? 'projects'
94
        # if only one project is found, user is redirected to its overview
95
        redirect_to :controller => 'projects', :action => 'show', :id => @results.first and return if @results.size == 1
97
        @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
98
        if @results.size > limit
99
          @pagination_previous_date = @results[-(limit)].event_datetime 
100
          @results = @results[-(limit), limit]
101
        end
96 102
      end
97 103
    else
98 104
      @question = ""
app/views/search/index.rhtml (working copy)
11 11
<br />
12 12
<label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label>
13 13
<label><%= check_box_tag 'titles_only', 1, @titles_only %> <%= l(:label_search_titles_only) %></label>
14
<% if @project %> 
15
  <label><%= check_box_tag 'all_projects',1,@all_projects %> <%= l(:label_all_projects) %></label>
16
<% end%>
14 17
</p>
15 18
<%= submit_tag l(:button_submit), :name => 'submit' %>
16 19
<% end %>
......
22 25
      <% @results.each do |e| %>
23 26
        <li><p><%= link_to highlight_tokens(truncate(e.event_title, 255), @tokens), e.event_url %><br />
24 27
        <%= highlight_tokens(e.event_description, @tokens) %><br />
28
		<% if @all_projects and e.respond_to?('project') %>
29
		  <span class="author"><%= l(:label_in_project) %> <%= e.project.name %><br />
30
		<% end %>
25 31
        <span class="author"><%= format_time(e.event_datetime) %></span></p></li>
26 32
      <% end %>
27 33
    </ul>
lang/en.yml (working copy)
410 410
label_roadmap_no_issues: No issues for this version
411 411
label_search: Search
412 412
label_result_plural: Results
413
label_in_project: in
414
label_all_projects: All projects
413 415
label_all_words: All words
414 416
label_wiki: Wiki
415 417
label_wiki_edit: Wiki edit
vendor/plugins/acts_as_searchable/lib/acts_as_searchable.rb (working copy)
90 90
            if options[:offset]
91 91
              sql = "(#{sql}) AND (#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
92 92
            end
93
            
94
            if project.is_a?(Array)
95
              sql += " AND #{searchable_options[:project_key]} IN (#{project.collect(&:id).join(',')})"
96
            else
97
              sql += " AND #{searchable_options[:project_key]} = #{project.id}"
98
            end
99

  
93 100
            find_options[:conditions] = [sql, * (tokens * token_clauses.size).sort]
94 101
            
95
            results = with_scope(:find => {:conditions => ["#{searchable_options[:project_key]} = ?", project.id]}) do
96
              find(:all, find_options)
97
            end            
102
            results = find(:all, find_options)
103
            
98 104
            if searchable_options[:with] && !options[:titles_only]
99 105
              searchable_options[:with].each do |model, assoc|
100 106
                results += model.to_s.camelcase.constantize.search(tokens, project, options).collect {|r| r.send assoc}
(5-5/5)