I finally felt comfortable enough to do the final conversion of WikiController
to a REST resource. Yesterday’s refactoring of the :id
parameter make this a lot easier.
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 |
# config/routes.rb map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post} map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get} map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post} map.with_options :controller => 'wiki' do |wiki_routes| wiki_routes.with_options :conditions => {:method => :get} do |wiki_views| wiki_views.connect 'projects/:project_id/wiki/export', :action => 'export' wiki_views.connect 'projects/:project_id/wiki/index', :action => 'index' wiki_views.connect 'projects/:project_id/wiki/date_index', :action => 'date_index' wiki_views.connect 'projects/:project_id/wiki/:id', :action => 'show', :id => nil wiki_views.connect 'projects/:project_id/wiki/:id/edit', :action => 'edit' wiki_views.connect 'projects/:project_id/wiki/:id/rename', :action => 'rename' wiki_views.connect 'projects/:project_id/wiki/:id/history', :action => 'history' wiki_views.connect 'projects/:project_id/wiki/:id/diff/:version/vs/:version_from', :action => 'diff' wiki_views.connect 'projects/:project_id/wiki/:id/annotate/:version', :action => 'annotate' end wiki_routes.connect 'projects/:project_id/wiki/:id/:action', :action => /rename|preview|protect|add_attachment/, :conditions => {:method => :post} wiki_routes.connect 'projects/:project_id/wiki/:id/edit', :action => 'update', :conditions => {:method => :post} wiki_routes.connect 'projects/:project_id/wiki/:id', :action => 'destroy', :conditions => {:method => :delete} end # Project routes map.resources :projects, :member => { :copy => [:get, :post], :settings => :get, :modules => :post, :archive => :post, :unarchive => :post } do |project| project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy] project.resources :files, :only => [:index, :new, :create] project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post} project.resources :news, :shallow => true project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id' 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 |
# config/routes.rb map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post} map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get} map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post} # No more 'wiki' routing # Project routes map.resources :projects, :member => { :copy => [:get, :post], :settings => :get, :modules => :post, :archive => :post, :unarchive => :post } do |project| project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy] project.resources :files, :only => [:index, :new, :create] project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post} project.resources :news, :shallow => true project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id' project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get} project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get} project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff' project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate' project.resources :wiki, :except => [:new, :create], :member => { :rename => [:get, :post], :history => :get, :preview => :any, :protect => :post, :add_attachment => :post }, :collection => { :export => :get, :date_index => :get } end |
Because of the odd routing in WikiController
, I had to add some additional routes so everything would work.
Wiki Start Page
Redmine has a concept of a Wiki Start Page. This page is the default page that is shown when first browsing to a wiki. In reality though, the page has an title but it’s masked in the url routing. To handle it, I used the project_wiki_start_page
named route and pointed it to the :show
action.
Wiki Index
Since the Wiki Start Page takes over the path for standard #index
action for the resource, a second route has to be defined to handle the #index
. This departs from the Rails conventions but I can’t think of a better way to handle this.
Wiki Diff and Wiki Annotate
Custom routes had to be added to support the pretty urls for showing diffs and annotations of wiki pages. Since they are only views on the resource, they are quite simple.
Custom member and collection actions
Since WikiController
still has a bunch of actions, I had to define them in the resource definition so their routes can be generated. Eventually, most of these should be refactored to other controllers or merged into the standard actions.
With this refactoring, I now have enough of Redmine’s controllers converted to REST resources so that I can start working on Redmine 1.1’s new APIs. I think I’ll be taking a break for tomorrow’s refactoring while I think about what my next steps are.
- continue this refactoring series and start refactoring the controller methods
- continue this refactoring series and start refactoring other controllers to convert them to resources (Redmine 1.2’s APIs)
- pause refactoring and do some posts on implementing Redmine’s new APIs
- or some other idea that I haven’t thought about yet
What would you be interested in reading about?
Thanks for these interesting posts on refactoring.
You might like to correct the typo (were -> where) in your “About” signature.
Thanks