Skip to content

Commit 7034272

Browse files
committed
Add destroyed? to ActiveRecord, include tests for polymorphic urls for destroyed objects and refactor mime responds tests and documentation.
1 parent f59984c commit 7034272

File tree

8 files changed

+133
-76
lines changed

8 files changed

+133
-76
lines changed

actionpack/lib/action_controller/metal/mime_responds.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,37 @@ def respond_to(*mimes, &block)
330330
# In this case, since @person.destroyed? returns true, polymorphic urls will
331331
# redirect to the collection url, instead of the resource url.
332332
#
333+
# === Nested resources
334+
#
335+
# respond_with also works with nested resources, you just need to pass them
336+
# as you do in form_for and polymorphic_url. Consider the project has many
337+
# tasks example. The create action for TasksController would be like:
338+
#
339+
# def create
340+
# @project = Project.find(params[:project_id])
341+
# @task = @project.comments.build(params[:task])
342+
# @task.save
343+
# respond_with([@project, @task])
344+
# end
345+
#
346+
# Namespaced and singleton resources requires a symbol to be given, as in
347+
# polymorphic urls. If a project has one manager with has many tasks, it
348+
# should be invoked as:
349+
#
350+
# respond_with([@project, :manager, @task])
351+
#
352+
# Be sure to check polymorphic_url documentation. The only occasion you will
353+
# need to give clear input to respond_with is in DELETE verbs for singleton
354+
# resources. In such cases, the collection url does not exist, so you need
355+
# to supply the destination url after delete:
356+
#
357+
# def destroy
358+
# @project = Project.find(params[:project_id])
359+
# @manager = @project.manager
360+
# @manager.destroy
361+
# respond_with([@project, @manager], :location => root_url)
362+
# end
363+
#
333364
def respond_with(resource, options={}, &block)
334365
respond_to(&block)
335366
rescue ActionView::MissingTemplate => e

actionpack/test/activerecord/polymorphic_routes_test.rb

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ def test_with_new_record
5252
end
5353
end
5454

55+
def test_with_destroyed_record
56+
with_test_routes do
57+
@project.destroy
58+
assert_equal "http://example.com/projects", polymorphic_url(@project)
59+
end
60+
end
61+
5562
def test_with_record_and_action
5663
with_test_routes do
5764
assert_equal "http://example.com/projects/new", polymorphic_url(@project, :action => 'new')
@@ -129,6 +136,14 @@ def test_with_nested_unsaved
129136
end
130137
end
131138

139+
def test_with_nested_destroyed
140+
with_test_routes do
141+
@project.save
142+
@task.destroy
143+
assert_equal "http://example.com/projects/#{@project.id}/tasks", polymorphic_url([@project, @task])
144+
end
145+
end
146+
132147
def test_new_with_array_and_namespace
133148
with_admin_test_routes do
134149
assert_equal "http://example.com/admin/projects/new", polymorphic_url([:admin, @project], :action => 'new')
@@ -257,6 +272,13 @@ def test_with_irregular_plural_new_record
257272
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
258273
end
259274
end
275+
276+
def test_with_irregular_plural_destroyed_record
277+
with_test_routes do
278+
@tax.destroy
279+
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
280+
end
281+
end
260282

261283
def test_with_irregular_plural_record_and_action
262284
with_test_routes do
@@ -395,4 +417,4 @@ def with_admin_and_site_test_routes(options = {})
395417
end
396418
end
397419

398-
end
420+
end

actionpack/test/controller/mime_responds_test.rb

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'abstract_unit'
2+
require 'controller/fake_models'
23

34
class RespondToController < ActionController::Base
45
layout :set_layout
@@ -471,44 +472,6 @@ def test_format_with_custom_response_type_and_request_headers
471472
end
472473
end
473474

474-
class RespondResource
475-
undef_method :to_json
476-
477-
def self.model_name
478-
@_model_name ||= ActiveModel::Name.new("resource")
479-
end
480-
481-
def to_param
482-
13
483-
end
484-
485-
def to_xml
486-
"XML"
487-
end
488-
489-
def to_js
490-
"JS"
491-
end
492-
493-
def errors
494-
[]
495-
end
496-
497-
def destroyed?
498-
false
499-
end
500-
end
501-
502-
class ParentResource
503-
def self.model_name
504-
@_model_name ||= ActiveModel::Name.new("parent")
505-
end
506-
507-
def to_param
508-
11
509-
end
510-
end
511-
512475
class RespondWithController < ActionController::Base
513476
respond_to :html, :json
514477
respond_to :xml, :except => :using_defaults
@@ -531,17 +494,17 @@ def default_overwritten
531494
end
532495

533496
def using_resource
534-
respond_with(RespondResource.new)
497+
respond_with(Customer.new("david", 13))
535498
end
536499

537500
def using_resource_with_options
538-
respond_with(RespondResource.new, :status => :unprocessable_entity) do |format|
501+
respond_with(Customer.new("david", 13), :status => :unprocessable_entity) do |format|
539502
format.js
540503
end
541504
end
542505

543506
def using_resource_with_parent
544-
respond_with([ParentResource.new, RespondResource.new])
507+
respond_with([Quiz::Store.new("developer?", 11), Customer.new("david", 13)])
545508
end
546509

547510
protected
@@ -550,26 +513,14 @@ def _render_js(js, options)
550513
self.content_type ||= Mime::JS
551514
self.response_body = js.respond_to?(:to_js) ? js.to_js : js
552515
end
553-
554-
def resources_url
555-
request.host + "/resources"
556-
end
557-
558-
def resource_url(resource)
559-
request.host + "/resources/#{resource.to_param}"
560-
end
561-
562-
def parent_resource_url(parent, resource)
563-
request.host + "/parents/#{parent.to_param}/resources/#{resource.to_param}"
564-
end
565516
end
566517

567518
class InheritedRespondWithController < RespondWithController
568519
clear_respond_to
569520
respond_to :xml, :json
570521

571522
def index
572-
respond_with(RespondResource.new) do |format|
523+
respond_with(Customer.new("david", 13)) do |format|
573524
format.json { render :text => "JSON" }
574525
end
575526
end
@@ -582,6 +533,11 @@ def setup
582533
super
583534
ActionController::Base.use_accept_header = true
584535
@request.host = "www.example.com"
536+
537+
ActionController::Routing::Routes.draw do |map|
538+
map.resources :customers
539+
map.resources :quiz_stores, :has_many => :customers
540+
end
585541
end
586542

587543
def teardown
@@ -645,11 +601,11 @@ def test_using_resource_for_post_with_html
645601
post :using_resource
646602
assert_equal "text/html", @response.content_type
647603
assert_equal 302, @response.status
648-
assert_equal "www.example.com/resources/13", @response.location
604+
assert_equal "http://www.example.com/customers/13", @response.location
649605
assert @response.redirect?
650606

651607
errors = { :name => :invalid }
652-
RespondResource.any_instance.stubs(:errors).returns(errors)
608+
Customer.any_instance.stubs(:errors).returns(errors)
653609
post :using_resource
654610
assert_equal "text/html", @response.content_type
655611
assert_equal 200, @response.status
@@ -664,10 +620,10 @@ def test_using_resource_for_post_with_xml
664620
assert_equal "application/xml", @response.content_type
665621
assert_equal 201, @response.status
666622
assert_equal "XML", @response.body
667-
assert_equal "www.example.com/resources/13", @response.location
623+
assert_equal "http://www.example.com/customers/13", @response.location
668624

669625
errors = { :name => :invalid }
670-
RespondResource.any_instance.stubs(:errors).returns(errors)
626+
Customer.any_instance.stubs(:errors).returns(errors)
671627
post :using_resource
672628
assert_equal "application/xml", @response.content_type
673629
assert_equal 422, @response.status
@@ -679,11 +635,11 @@ def test_using_resource_for_put_with_html
679635
put :using_resource
680636
assert_equal "text/html", @response.content_type
681637
assert_equal 302, @response.status
682-
assert_equal "www.example.com/resources/13", @response.location
638+
assert_equal "http://www.example.com/customers/13", @response.location
683639
assert @response.redirect?
684640

685641
errors = { :name => :invalid }
686-
RespondResource.any_instance.stubs(:errors).returns(errors)
642+
Customer.any_instance.stubs(:errors).returns(errors)
687643
put :using_resource
688644
assert_equal "text/html", @response.content_type
689645
assert_equal 200, @response.status
@@ -698,10 +654,10 @@ def test_using_resource_for_put_with_xml
698654
assert_equal "application/xml", @response.content_type
699655
assert_equal 200, @response.status
700656
assert_equal " ", @response.body
701-
assert_equal "www.example.com/resources/13", @response.location
657+
assert_equal "http://www.example.com/customers/13", @response.location
702658

703659
errors = { :name => :invalid }
704-
RespondResource.any_instance.stubs(:errors).returns(errors)
660+
Customer.any_instance.stubs(:errors).returns(errors)
705661
put :using_resource
706662
assert_equal "application/xml", @response.content_type
707663
assert_equal 422, @response.status
@@ -710,21 +666,21 @@ def test_using_resource_for_put_with_xml
710666
end
711667

712668
def test_using_resource_for_delete_with_html
713-
RespondResource.any_instance.stubs(:destroyed?).returns(true)
669+
Customer.any_instance.stubs(:destroyed?).returns(true)
714670
delete :using_resource
715671
assert_equal "text/html", @response.content_type
716672
assert_equal 302, @response.status
717-
assert_equal "www.example.com/resources", @response.location
673+
assert_equal "http://www.example.com/customers", @response.location
718674
end
719675

720676
def test_using_resource_for_delete_with_xml
721-
RespondResource.any_instance.stubs(:destroyed?).returns(true)
677+
Customer.any_instance.stubs(:destroyed?).returns(true)
722678
@request.accept = "application/xml"
723679
delete :using_resource
724680
assert_equal "application/xml", @response.content_type
725681
assert_equal 200, @response.status
726682
assert_equal " ", @response.body
727-
assert_equal "www.example.com/resources", @response.location
683+
assert_equal "http://www.example.com/customers", @response.location
728684
end
729685

730686
def test_using_resource_with_options
@@ -756,10 +712,10 @@ def test_using_resource_with_parent_for_post
756712
assert_equal "application/xml", @response.content_type
757713
assert_equal 201, @response.status
758714
assert_equal "XML", @response.body
759-
assert_equal "www.example.com/parents/11/resources/13", @response.location
715+
assert_equal "http://www.example.com/quiz_stores/11/customers/13", @response.location
760716

761717
errors = { :name => :invalid }
762-
RespondResource.any_instance.stubs(:errors).returns(errors)
718+
Customer.any_instance.stubs(:errors).returns(errors)
763719
post :using_resource
764720
assert_equal "application/xml", @response.content_type
765721
assert_equal 422, @response.status

actionpack/test/controller/render_test.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ def head_with_location_header
459459
end
460460

461461
def head_with_location_object
462-
head :location => Customer.new("david")
462+
head :location => Customer.new("david", 1)
463463
end
464464

465465
def head_with_symbolic_status
@@ -622,9 +622,6 @@ def rescue_action(e)
622622
end
623623

624624
private
625-
def customer_url(customer)
626-
request.host + "/customers/1"
627-
end
628625

629626
def determine_layout
630627
case action_name
@@ -1093,9 +1090,14 @@ def test_head_with_location_header
10931090
end
10941091

10951092
def test_head_with_location_object
1093+
ActionController::Routing::Routes.draw do |map|
1094+
map.resources :customers
1095+
map.connect ':controller/:action/:id'
1096+
end
1097+
10961098
get :head_with_location_object
10971099
assert @response.body.blank?
1098-
assert_equal "www.nextangle.com/customers/1", @response.headers["Location"]
1100+
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
10991101
assert_response :ok
11001102
end
11011103

actionpack/test/controller/render_xml_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def render_with_location
1111

1212
def render_with_object_location
1313
customer = Customer.new("Some guy", 1)
14-
render :xml => "<customer/>", :location => customer_url(customer), :status => :created
14+
render :xml => "<customer/>", :location => customer, :status => :created
1515
end
1616

1717
def render_with_to_xml
@@ -78,4 +78,4 @@ def test_should_use_implicit_content_type
7878
get :implicit_content_type, :format => 'atom'
7979
assert_equal Mime::ATOM, @response.content_type
8080
end
81-
end
81+
end

actionpack/test/lib/controller/fake_models.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,27 @@ class Customer < Struct.new(:name, :id)
44
extend ActiveModel::Naming
55
include ActiveModel::Conversion
66

7+
undef_method :to_json
8+
79
def to_param
810
id.to_s
911
end
12+
13+
def to_xml
14+
"XML"
15+
end
16+
17+
def to_js
18+
"JS"
19+
end
20+
21+
def errors
22+
[]
23+
end
24+
25+
def destroyed?
26+
false
27+
end
1028
end
1129

1230
class BadCustomer < Customer
@@ -24,4 +42,8 @@ def to_param
2442
id.to_s
2543
end
2644
end
45+
46+
class Store < Question
47+
end
2748
end
49+

0 commit comments

Comments
 (0)