tales of failure and woe

 

from twitter  

 

Creating an ActiveResource compatible controller

Recently I found myself needing to create a resource-only controller, no HTML, no views, just straight-up XML data. I was planning on using ActiveResource to interact with my resource server. I could find lots of resources on using ActiveResource as a client, but not much in the way of building a proper controller with the intention of working in conjunction with ActiveResource as the consumer. Here is what I’ve worked up:

UPDATE: It looks like Mephisto mangled the code pretty bad so here are links to the actual files:

contacts_controller.rb
contacts_controller_spec.rb

contacts_controller.rb

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

class ContactsController < ApplicationController
  before_filter :find_or_initialize_contact, :except => [ :index ]

  # GET /contacts
  # Formats: xml
  def index
    @contacts = Contact.find(:all)
    respond_to do |format|
      format.html { head :method_not_allowed }
      
      format.xml { render :xml => @contacts.to_xml }
    end
  end

  # POST /contacts
  # Formats: xml
  def create
    respond_to do |format|
      format.html { head :method_not_allowed }
      
      if @contact.save
        format.xml { headers['Location'] = contact_url(@contact); render :xml => @contact.to_xml, :status => :created }
      else
        format.xml { render :xml => @contact.errors.to_xml, :status => :unprocessable_entity }
      end
    end
  end
  
  # GET /contacts/<id>
  # Formats: xml
  def show
    respond_to do |format|
      format.html { head :method_not_allowed }
      format.xml { render :xml => @contact.to_xml }
    end
  end
  
  # PUT /contacts/<id>
  # Formats: xml
  def update
    respond_to do |format|
      format.html { head :method_not_allowed }

      if @contact.update_attributes(params[:contact])
        format.xml { render :xml => @contact.to_xml }
      else
        format.xml { render :xml => @contact.errors.to_xml, :status => :unprocessable_entity }
      end
    end
  end
  
  # DELETE /contacts/<id>
  # Formats: xml
  def destroy
    respond_to do |format|
      format.html { head :method_not_allowed }
      
      if @contact.destroy
        format.xml { head :ok }
      else
        format.xml { render :xml => @contact.errors.to_xml, :status => :unprocessable_entity }
      end
    end
  end
  
  def find_or_initialize_contact
    if params[:id]
      unless @contact = Contact.find_by_id(params[:id])
        render_optional_error_file :not_found
      end
    else
      @contact = Contact.new(params[:contact])
    end
  end
  
end

contacts_controller_spec.rb

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131


describe ContactsController, 'get /contacts' do
  before(:each) do
    @request.env["HTTP_ACCEPT"] = "application/xml"
    @contact = Contact.create(:first_name => 'John', :last_name => 'Smith')
    Contact.stub!(:find_by_id).and_return(@contact)
  end

  it 'should return 405 (Method Not Allowed) if HTTP_ACCEPT is text/html' do
    @request.env["HTTP_ACCEPT"] = "text/html"
    get :index
    response.response_code.should == 405
  end
  
  it 'should return success' do
    get :index
    response.should be_success
  end
end

describe ContactsController, 'post /contacts' do
  before(:each) do
    @request.env["HTTP_ACCEPT"] = "application/xml"
  end
  
  it 'should return 405 (Method Not Allowed) if HTTP_ACCEPT is text/html' do
    @request.env["HTTP_ACCEPT"] = "text/html"
    post :create
    response.response_code.should == 405
  end

  it 'should return 201 (Created)' do
    post :create, :contact => { :first_name => 'John', :last_name => 'Smith' }
    response.response_code.should == 201
  end

  it 'should return 422 (Unprocessable Entity) if create fails' do
    post :create
    response.response_code.should == 422
  end
end

describe ContactsController, 'get /contacts/<id>' do
  before(:each) do
    @request.env["HTTP_ACCEPT"] = "application/xml"
    @contact = Contact.create(:first_name => 'John', :last_name => 'Smith')
    Contact.stub!(:find_by_id).and_return(@contact)
  end

  it 'should return 405 (Method Not Allowed) if HTTP_ACCEPT is text/html' do
    @request.env["HTTP_ACCEPT"] = "text/html"
    get :show, :id => @contact.id
    response.response_code.should == 405
  end
  
  it 'should return success' do
    get :show, :id => @contact.id
    response.should be_success
  end
  
  it 'should return 404 (Not Found) if record does not exist' do
    Contact.should_receive(:find_by_id).with('0').and_return(nil)
    get :show, :id => 0
    response.response_code.should == 404
  end
end

describe ContactsController, 'put /contacts/<id>' do
  before(:each) do
    @request.env["HTTP_ACCEPT"] = "application/xml"
    @contact = Contact.create(:first_name => 'John', :last_name => 'Smith')
    Contact.stub!(:find_by_id).and_return(@contact)
  end

  it 'should return 405 (Method Not Allowed) if HTTP_ACCEPT is text/html' do
    @request.env["HTTP_ACCEPT"] = "text/html"
    put :update, :id => @contact.id
    response.response_code.should == 405
  end
  
  it 'should return success' do
    put :update, :id => @contact.id, :contact => { :first_name => 'Sam' }
    response.should be_success
    @contact.name.should == 'new test site'
  end

  it 'should return 422 (Unprocessable Entity) if update fails' do
    @contact.should_receive(:update_attributes).and_return(nil)
    put :update, :id => @contact.id, :contact => { :first_name => 'Sam' }
    response.response_code.should == 422
  end
  
  
  it 'should return 404 (Not Found) if record does not exist' do
    Contact.should_receive(:find_by_id).with('0').and_return(nil)
    put :update, :id => 0, :contact => { :first_name => 'Sam' }
    response.response_code.should == 404
  end
end

describe ContactsController, 'delete /contacts/<id>' do
  before(:each) do
    @request.env["HTTP_ACCEPT"] = "application/xml"
    @contact = Contact.create(:first_name => 'John', :last_name => 'Smith')
    Contact.stub!(:find_by_id).and_return(@contact)
  end

  it 'should return 405 (Method Not Allowed) if HTTP_ACCEPT is text/html' do
    @request.env["HTTP_ACCEPT"] = "text/html"
    delete :destroy, :id => @contact.id
    response.response_code.should == 405
  end
  
  it 'should return success' do
    delete :destroy, :id => @contact.id
    response.should be_success
  end

  it 'should return 422 (Unprocessable Entity) if destroy fails' do
    @contact.should_receive(:destroy).and_return(nil)
    delete :destroy, :id => @contact.id
    response.response_code.should == 422
  end
  
  it 'should return 404 (Not Found) if record does not exist' do
    Contact.should_receive(:find_by_id).with('0').and_return(nil)
    delete :destroy, :id => 0
    response.response_code.should == 404
  end
end

Leave a Reply