To wrap up this week’s refactoring of IssuesController
, I used merge method to merge the #update_form
action into #new
. The #update_form
method is an Ajax endpoint that is used to refresh an issue form’s fields. For example, when an issue form changes from Bug to Feature it needs to load the fields for a Feature.
Before
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
class IssuesController [:new, :create, :update_form] def new render :action => 'new', :layout => !request.xhr? end def update_form if params[:id].blank? @issue = Issue.new @issue.project = @project else @issue = @project.issues.visible.find(params[:id]) end @issue.attributes = params[:issue] @allowed_statuses = ([@issue.status] + @issue.status.find_new_statuses_allowed_to(User.current.roles_for_project(@project), @issue.tracker)).uniq @priorities = IssuePriority.all render :partial => 'attributes' end private def build_new_issue_from_params @issue = Issue.new @issue.copy_from(params[:copy_from]) if params[:copy_from] @issue.project = @project # Tracker must be set before custom field values @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) if @issue.tracker.nil? render_error l(:error_no_tracker_in_project) return false end if params[:issue].is_a?(Hash) @issue.safe_attributes = params[:issue] @issue.watcher_user_ids = params[:issue]['watcher_user_ids'] if User.current.allowed_to?(:add_issue_watchers, @project) end @issue.author = User.current @issue.start_date ||= Date.today @priorities = IssuePriority.all @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) end end |
After
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
class IssuesController [:new, :create] def new respond_to do |format| format.html { render :action => 'new', :layout => !request.xhr? } format.js { render :partial => 'attributes' } end end # No more update_form method # TODO: Refactor, lots of extra code in here def build_new_issue_from_params if params[:id].blank? @issue = Issue.new @issue.copy_from(params[:copy_from]) if params[:copy_from] @issue.project = @project else @issue = @project.issues.visible.find(params[:id]) end @issue.project = @project # Tracker must be set before custom field values @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first) if @issue.tracker.nil? render_error l(:error_no_tracker_in_project) return false end if params[:issue].is_a?(Hash) @issue.safe_attributes = params[:issue] @issue.watcher_user_ids = params[:issue]['watcher_user_ids'] if User.current.allowed_to?(:add_issue_watchers, @project) end @issue.author = User.current @issue.start_date ||= Date.today @priorities = IssuePriority.all @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) end end |
This was a good refactoring for a few reasons.
First, it lets me remove another non REST method from IssuesController
.
Second, #update_form
was using some older queries that were refactored some time ago. For example this query was moved to Issue#new_statuses_allowed
over a year ago but #update_form
was never updated.
1 |
@allowed_statuses = ([@issue.status] + @issue.status.find_new_statuses_allowed_to(User.current.roles_for_project(@project), @issue.tracker)).uniq |
Third, on a conceptual level, #update_form
was loading the same resource as #new
but with a different response format (:js). This meant using respond_to
with the two different formats would make perfect sense and would also let both formats share all of the setup code.