Daily Refactor #80: Convert PaymentsController to REST Controller

The Refactoring

Following up on yesterday’s refactoring, today I converted the PaymentsController to a REST controller.

Before

1
2
3
4
5
6
7
8
9
10
11
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources(:invoice,
                :collection => {
                  :autocreate => :get,
                  :autofill => :get
                },
                :member => {
                  :outstanding => :get
                })
end
1
2
3
4
5
6
7
8
# test/integration/routing_test.rb
require "#{File.dirname(__FILE__)}/../test_helper"
 
class RoutingTest  'payments', :action => 'new'
 
    should_route :post, "/payments/create", :controller => 'payments', :action => 'create'
  end
end

After

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources(:invoice,
                :collection => {
                  :autocreate => :get,
                  :autofill => :get
                },
                :member => {
                  :outstanding => :get
                },
                :shallow => true) do |invoice|
    invoice.resources :payments, :only => [:new, :create]
  end
 
  map.resources :payments, :only => [:new, :create]
end
1
2
3
4
5
6
7
8
9
10
11
12
# test/integration/routing_test.rb
require "#{File.dirname(__FILE__)}/../test_helper"
 
class RoutingTest  'payments', :action => 'new'
 
    should_route :post, "/payments", :controller => 'payments', :action => 'create'
 
    should_route :get, "/invoice/100/payments/new", :controller => 'payments', :action => 'new', :invoice_id => '100'
 
    should_route :post, "/invoice/100/payments", :controller => 'payments', :action => 'create', :invoice_id => '100'
  end
end

Review

There is one smell I’d like to figure out from this refactoring. I couldn’t find why I needed to define both a shallow route (invoice.resources :payments) and a regular route (map.resources :payments). If I only had the shallow one defined, I couldn’t access PaymentsController#create at ‘/payments/ because it fell through to the default route (and the index action). If anyone has a suggestion about what’s wrong, let me know in the comments below.

Reference commit