Starting on my refactoring of Redmine’s ProjectsController, I used extract class to move the #activity method to a new controller. #activity is used to get a timeline of events on a project, so you can see what’s recently happened. Since it’s not tied to an actual project record, it doesn’t fit on ProjectsController.
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 44 45 46 47 | class ProjectsController :activity before_filter :find_optional_project, :only => :activity accept_key_auth :activity, :index def activity @days = Setting.activity_days_default.to_i if params[:from] begin; @date_to = params[:from].to_date + 1; rescue; end end @date_to ||= Date.today + 1 @date_from = @date_to - @days @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, :with_subprojects => @with_subprojects, :author => @author) @activity.scope_select {|t| !params["show_#{t}"].nil?} @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? events = @activity.events(@date_from, @date_to) if events.empty? || stale?(:etag => [events.first, User.current]) respond_to do |format| format.html { @events_by_day = events.group_by(&:event_date) render :layout => false if request.xhr? } format.atom { title = l(:label_activity) if @author title = @author.name elsif @activity.scope.size == 1 title = l("label_#{@activity.scope.first.singularize}_plural") end render_feed(events, :title => "#{@project || Setting.app_title}: #{title}") } end end rescue ActiveRecord::RecordNotFound render_404 end end |
After
1 2 3 | class ProjectsController < ApplicationController accept_key_auth :index end |
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 | class ActivitiesController @project, :with_subprojects => @with_subprojects, :author => @author) @activity.scope_select {|t| !params["show_#{t}"].nil?} @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? events = @activity.events(@date_from, @date_to) if events.empty? || stale?(:etag => [events.first, User.current]) respond_to do |format| format.html { @events_by_day = events.group_by(&:event_date) render :layout => false if request.xhr? } format.atom { title = l(:label_activity) if @author title = @author.name elsif @activity.scope.size == 1 title = l("label_#{@activity.scope.first.singularize}_plural") end render_feed(events, :title => "#{@project || Setting.app_title}: #{title}") } end end rescue ActiveRecord::RecordNotFound render_404 end private # TODO: refactor, duplicated in projects_controller def find_optional_project return true unless params[:id] @project = Project.find(params[:id]) authorize rescue ActiveRecord::RecordNotFound render_404 end end |
Other than the method move and rename, there isn’t that much to this refactoring.
The #find_optional_project method had to be copied over from ProjectsController since it was used as a before_filter, but I find that’s common when a controller is first split. Like other code smells I create intentionally, I used a comment with a “TODO” to mark it for later.
There are still quite a few methods in ProjectsController to be refactored. From the looks of it, some will end up in new controllers like this refactoring. While others will be merged into other actions.
Share
Related posts:
- Redmine Refactor #105: Move method from ProjectsController#save_activities to ProjectEnumerationsController#save
- Redmine Refactor #95: Extract ContextMenusController from IssuesController
- Redmine Refactor #94: Extract PreviewsController from IssuesController
- Redmine Refactor #93: Extract Controller from IssuesController
- Daily Refactor #68: Extract Class to New Controller
