Navigation Menu

Skip to content

Commit

Permalink
Add destroyed? to ActiveRecord, include tests for polymorphic urls fo…
Browse files Browse the repository at this point in the history
…r destroyed objects and refactor mime responds tests and documentation.
  • Loading branch information
josevalim committed Aug 7, 2009
1 parent f59984c commit 7034272
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 76 deletions.
31 changes: 31 additions & 0 deletions actionpack/lib/action_controller/metal/mime_responds.rb
Expand Up @@ -330,6 +330,37 @@ def respond_to(*mimes, &block)
# In this case, since @person.destroyed? returns true, polymorphic urls will
# redirect to the collection url, instead of the resource url.
#
# === Nested resources
#
# respond_with also works with nested resources, you just need to pass them
# as you do in form_for and polymorphic_url. Consider the project has many
# tasks example. The create action for TasksController would be like:
#
# def create
# @project = Project.find(params[:project_id])
# @task = @project.comments.build(params[:task])
# @task.save
# respond_with([@project, @task])
# end
#
# Namespaced and singleton resources requires a symbol to be given, as in
# polymorphic urls. If a project has one manager with has many tasks, it
# should be invoked as:
#
# respond_with([@project, :manager, @task])
#
# Be sure to check polymorphic_url documentation. The only occasion you will
# need to give clear input to respond_with is in DELETE verbs for singleton
# resources. In such cases, the collection url does not exist, so you need
# to supply the destination url after delete:
#
# def destroy
# @project = Project.find(params[:project_id])
# @manager = @project.manager
# @manager.destroy
# respond_with([@project, @manager], :location => root_url)
# end
#
def respond_with(resource, options={}, &block)
respond_to(&block)
rescue ActionView::MissingTemplate => e
Expand Down
24 changes: 23 additions & 1 deletion actionpack/test/activerecord/polymorphic_routes_test.rb
Expand Up @@ -52,6 +52,13 @@ def test_with_new_record
end
end

def test_with_destroyed_record
with_test_routes do
@project.destroy
assert_equal "http://example.com/projects", polymorphic_url(@project)
end
end

def test_with_record_and_action
with_test_routes do
assert_equal "http://example.com/projects/new", polymorphic_url(@project, :action => 'new')
Expand Down Expand Up @@ -129,6 +136,14 @@ def test_with_nested_unsaved
end
end

def test_with_nested_destroyed
with_test_routes do
@project.save
@task.destroy
assert_equal "http://example.com/projects/#{@project.id}/tasks", polymorphic_url([@project, @task])
end
end

def test_new_with_array_and_namespace
with_admin_test_routes do
assert_equal "http://example.com/admin/projects/new", polymorphic_url([:admin, @project], :action => 'new')
Expand Down Expand Up @@ -257,6 +272,13 @@ def test_with_irregular_plural_new_record
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
end
end

def test_with_irregular_plural_destroyed_record
with_test_routes do
@tax.destroy
assert_equal "http://example.com/taxes", polymorphic_url(@tax)
end
end

def test_with_irregular_plural_record_and_action
with_test_routes do
Expand Down Expand Up @@ -395,4 +417,4 @@ def with_admin_and_site_test_routes(options = {})
end
end

end
end
92 changes: 24 additions & 68 deletions actionpack/test/controller/mime_responds_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
require 'controller/fake_models'

class RespondToController < ActionController::Base
layout :set_layout
Expand Down Expand Up @@ -471,44 +472,6 @@ def test_format_with_custom_response_type_and_request_headers
end
end

class RespondResource
undef_method :to_json

def self.model_name
@_model_name ||= ActiveModel::Name.new("resource")
end

def to_param
13
end

def to_xml
"XML"
end

def to_js
"JS"
end

def errors
[]
end

def destroyed?
false
end
end

class ParentResource
def self.model_name
@_model_name ||= ActiveModel::Name.new("parent")
end

def to_param
11
end
end

class RespondWithController < ActionController::Base
respond_to :html, :json
respond_to :xml, :except => :using_defaults
Expand All @@ -531,17 +494,17 @@ def default_overwritten
end

def using_resource
respond_with(RespondResource.new)
respond_with(Customer.new("david", 13))
end

def using_resource_with_options
respond_with(RespondResource.new, :status => :unprocessable_entity) do |format|
respond_with(Customer.new("david", 13), :status => :unprocessable_entity) do |format|
format.js
end
end

def using_resource_with_parent
respond_with([ParentResource.new, RespondResource.new])
respond_with([Quiz::Store.new("developer?", 11), Customer.new("david", 13)])
end

protected
Expand All @@ -550,26 +513,14 @@ def _render_js(js, options)
self.content_type ||= Mime::JS
self.response_body = js.respond_to?(:to_js) ? js.to_js : js
end

def resources_url
request.host + "/resources"
end

def resource_url(resource)
request.host + "/resources/#{resource.to_param}"
end

def parent_resource_url(parent, resource)
request.host + "/parents/#{parent.to_param}/resources/#{resource.to_param}"
end
end

class InheritedRespondWithController < RespondWithController
clear_respond_to
respond_to :xml, :json

def index
respond_with(RespondResource.new) do |format|
respond_with(Customer.new("david", 13)) do |format|
format.json { render :text => "JSON" }
end
end
Expand All @@ -582,6 +533,11 @@ def setup
super
ActionController::Base.use_accept_header = true
@request.host = "www.example.com"

ActionController::Routing::Routes.draw do |map|
map.resources :customers
map.resources :quiz_stores, :has_many => :customers
end
end

def teardown
Expand Down Expand Up @@ -645,11 +601,11 @@ def test_using_resource_for_post_with_html
post :using_resource
assert_equal "text/html", @response.content_type
assert_equal 302, @response.status
assert_equal "www.example.com/resources/13", @response.location
assert_equal "http://www.example.com/customers/13", @response.location
assert @response.redirect?

errors = { :name => :invalid }
RespondResource.any_instance.stubs(:errors).returns(errors)
Customer.any_instance.stubs(:errors).returns(errors)
post :using_resource
assert_equal "text/html", @response.content_type
assert_equal 200, @response.status
Expand All @@ -664,10 +620,10 @@ def test_using_resource_for_post_with_xml
assert_equal "application/xml", @response.content_type
assert_equal 201, @response.status
assert_equal "XML", @response.body
assert_equal "www.example.com/resources/13", @response.location
assert_equal "http://www.example.com/customers/13", @response.location

errors = { :name => :invalid }
RespondResource.any_instance.stubs(:errors).returns(errors)
Customer.any_instance.stubs(:errors).returns(errors)
post :using_resource
assert_equal "application/xml", @response.content_type
assert_equal 422, @response.status
Expand All @@ -679,11 +635,11 @@ def test_using_resource_for_put_with_html
put :using_resource
assert_equal "text/html", @response.content_type
assert_equal 302, @response.status
assert_equal "www.example.com/resources/13", @response.location
assert_equal "http://www.example.com/customers/13", @response.location
assert @response.redirect?

errors = { :name => :invalid }
RespondResource.any_instance.stubs(:errors).returns(errors)
Customer.any_instance.stubs(:errors).returns(errors)
put :using_resource
assert_equal "text/html", @response.content_type
assert_equal 200, @response.status
Expand All @@ -698,10 +654,10 @@ def test_using_resource_for_put_with_xml
assert_equal "application/xml", @response.content_type
assert_equal 200, @response.status
assert_equal " ", @response.body
assert_equal "www.example.com/resources/13", @response.location
assert_equal "http://www.example.com/customers/13", @response.location

errors = { :name => :invalid }
RespondResource.any_instance.stubs(:errors).returns(errors)
Customer.any_instance.stubs(:errors).returns(errors)
put :using_resource
assert_equal "application/xml", @response.content_type
assert_equal 422, @response.status
Expand All @@ -710,21 +666,21 @@ def test_using_resource_for_put_with_xml
end

def test_using_resource_for_delete_with_html
RespondResource.any_instance.stubs(:destroyed?).returns(true)
Customer.any_instance.stubs(:destroyed?).returns(true)
delete :using_resource
assert_equal "text/html", @response.content_type
assert_equal 302, @response.status
assert_equal "www.example.com/resources", @response.location
assert_equal "http://www.example.com/customers", @response.location
end

def test_using_resource_for_delete_with_xml
RespondResource.any_instance.stubs(:destroyed?).returns(true)
Customer.any_instance.stubs(:destroyed?).returns(true)
@request.accept = "application/xml"
delete :using_resource
assert_equal "application/xml", @response.content_type
assert_equal 200, @response.status
assert_equal " ", @response.body
assert_equal "www.example.com/resources", @response.location
assert_equal "http://www.example.com/customers", @response.location
end

def test_using_resource_with_options
Expand Down Expand Up @@ -756,10 +712,10 @@ def test_using_resource_with_parent_for_post
assert_equal "application/xml", @response.content_type
assert_equal 201, @response.status
assert_equal "XML", @response.body
assert_equal "www.example.com/parents/11/resources/13", @response.location
assert_equal "http://www.example.com/quiz_stores/11/customers/13", @response.location

errors = { :name => :invalid }
RespondResource.any_instance.stubs(:errors).returns(errors)
Customer.any_instance.stubs(:errors).returns(errors)
post :using_resource
assert_equal "application/xml", @response.content_type
assert_equal 422, @response.status
Expand Down
12 changes: 7 additions & 5 deletions actionpack/test/controller/render_test.rb
Expand Up @@ -459,7 +459,7 @@ def head_with_location_header
end

def head_with_location_object
head :location => Customer.new("david")
head :location => Customer.new("david", 1)
end

def head_with_symbolic_status
Expand Down Expand Up @@ -622,9 +622,6 @@ def rescue_action(e)
end

private
def customer_url(customer)
request.host + "/customers/1"
end

def determine_layout
case action_name
Expand Down Expand Up @@ -1093,9 +1090,14 @@ def test_head_with_location_header
end

def test_head_with_location_object
ActionController::Routing::Routes.draw do |map|
map.resources :customers
map.connect ':controller/:action/:id'
end

get :head_with_location_object
assert @response.body.blank?
assert_equal "www.nextangle.com/customers/1", @response.headers["Location"]
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
assert_response :ok
end

Expand Down
4 changes: 2 additions & 2 deletions actionpack/test/controller/render_xml_test.rb
Expand Up @@ -11,7 +11,7 @@ def render_with_location

def render_with_object_location
customer = Customer.new("Some guy", 1)
render :xml => "<customer/>", :location => customer_url(customer), :status => :created
render :xml => "<customer/>", :location => customer, :status => :created
end

def render_with_to_xml
Expand Down Expand Up @@ -78,4 +78,4 @@ def test_should_use_implicit_content_type
get :implicit_content_type, :format => 'atom'
assert_equal Mime::ATOM, @response.content_type
end
end
end
22 changes: 22 additions & 0 deletions actionpack/test/lib/controller/fake_models.rb
Expand Up @@ -4,9 +4,27 @@ class Customer < Struct.new(:name, :id)
extend ActiveModel::Naming
include ActiveModel::Conversion

undef_method :to_json

def to_param
id.to_s
end

def to_xml
"XML"
end

def to_js
"JS"
end

def errors
[]
end

def destroyed?
false
end
end

class BadCustomer < Customer
Expand All @@ -24,4 +42,8 @@ def to_param
id.to_s
end
end

class Store < Question
end
end

0 comments on commit 7034272

Please sign in to comment.