Redmine Refactor #93: Extract Controller from IssuesController

Continuing on the IssuesController refactoring, I used extract class to create a new controller for the #auto_complete action. This action is used to search for issues that match the text from a user. Redmine has several auto_complete actions scattered throughout different controllers that I’ve been wanting to unite into a single controller. Now AutoCompletesController can become that single controller.

Before

1
2
3
4
5
6
7
8
9
10
11
class IssuesController  [:new, :create, :update_form, :preview, :auto_complete]
 
  def auto_complete
    @issues = []
    q = params[:q].to_s
    if q.match(/^\d+$/)
      @issues < ["LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%"], :limit => 10)
    end
    render :layout => false
  end
end

After

1
2
3
class IssuesController < ApplicationController
  # ...
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class AutoCompletesController < ApplicationController
  before_filter :find_project
 
  def issues
    @issues = []
    q = params[:q].to_s
    if q.match(/^\d+$/)
      @issues < ["LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%"], :limit => 10)
    end
    render :layout => false
  end
 
  private
 
  def find_project
    project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id]
    @project = Project.find(project_id)
  rescue ActiveRecord::RecordNotFound
    render_404
  end
 
end

This refactoring makes it easier for other controllers to find and understand how to use the auto complete. It also removes another action from IssuesController, finally getting it under 400 lines of code.

Reference commit