Redmine Refactor #122: Convert NewsController to REST resource

This refactoring finally finishes converting the NewsController to a REST resource. Since I’ve done a lot refactoring last week, there isn’t much risk left in this conversion.

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
# config/routes.rb
  map.with_options :controller => 'news' do |news_routes|
    news_routes.connect 'news/:id/preview', :controller => 'previews', :action => 'news'
    news_routes.connect 'news/preview', :controller => 'previews', :action => 'news'
 
    news_routes.with_options :conditions => {:method => :get} do |news_views|
      news_views.connect 'news', :action => 'index'
      news_views.connect 'projects/:project_id/news', :action => 'index'
      news_views.connect 'projects/:project_id/news.:format', :action => 'index'
      news_views.connect 'news.:format', :action => 'index'
      news_views.connect 'projects/:project_id/news/new', :action => 'new'
      news_views.connect 'news/:id', :action => 'show'
      news_views.connect 'news/:id/edit', :action => 'edit'
    end
    news_routes.with_options do |news_actions|
      news_actions.connect 'projects/:project_id/news', :action => 'create', :conditions => {:method => :post}
      news_actions.connect 'news/:id/destroy', :action => 'destroy'
    end
    news_routes.connect 'news/:id/edit', :action => 'update', :conditions => {:method => :put}
 
    news_routes.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
    news_routes.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
  end
 
  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}
  end

After

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# config/routes.rb
  map.all_news 'news', :controller => 'news', :action => 'index'
  map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
  map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
  map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
  map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
 
  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
  end

By using a nested resource for :news with the shallow option, I was able to get most of the routes automatically. A few extra routes had to be added to support the different views:

  • All news and formatted news.
  • Preview route.
  • Routes for creating and deleting comments. These can be refactored to their own resource later on.

Now that News is done, I need to find the next controller to refactor. I’m thinking about the UsersController next. What do you think?

Reference commit