1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Split mime responder into smaller chunks and allow action to be configured.

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
José Valim 2009-11-11 14:45:21 -02:00 committed by Jeremy Kemper
parent a28d0ea33e
commit 2cb47c742f
2 changed files with 48 additions and 18 deletions

View file

@ -14,12 +14,11 @@ module ActionController #:nodoc:
#
# When a request comes, for example with format :xml, three steps happen:
#
# 1) respond_with searches for a template at people/index.xml;
# 1) responder searches for a template at people/index.xml;
#
# 2) if the template is not available, it will create a responder, passing
# the controller and the resource and invoke :to_xml on it;
# 2) if the template is not available, it will invoke :to_xml in the given resource;
#
# 3) if the responder does not respond_to :to_xml, call to_format on it.
# 3) if the responder does not respond_to :to_xml, call :to_format on it.
#
# === Builtin HTTP verb semantics
#
@ -88,14 +87,16 @@ module ActionController #:nodoc:
@resource = resources.is_a?(Array) ? resources.last : resources
@resources = resources
@options = options
@action = options.delete(:action)
@default_response = options.delete(:default_response)
end
delegate :head, :render, :redirect_to, :to => :controller
delegate :get?, :post?, :put?, :delete?, :to => :request
# Undefine :to_json since it's defined on Object
# Undefine :to_json and :to_yaml since it's defined on Object
undef_method(:to_json) if method_defined?(:to_json)
undef_method(:to_yaml) if method_defined?(:to_yaml)
# Initializes a new responder an invoke the proper format. If the format is
# not defined, call to_format.
@ -111,14 +112,8 @@ module ActionController #:nodoc:
#
def to_html
default_render
rescue ActionView::MissingTemplate
if get?
raise
elsif has_errors?
render :action => default_action
else
redirect_to resource_location
end
rescue ActionView::MissingTemplate => e
navigation_behavior(e)
end
# All others formats follow the procedure below. First we try to render a
@ -127,9 +122,26 @@ module ActionController #:nodoc:
#
def to_format
default_render
rescue ActionView::MissingTemplate
rescue ActionView::MissingTemplate => e
raise unless resourceful?
api_behavior(e)
end
protected
# This is the common behavior for "navigation" requests, like :html, :iphone and so forth.
def navigation_behavior(error)
if get?
raise error
elsif has_errors?
render :action => default_action
else
redirect_to resource_location
end
end
# This is the common behavior for "API" requests, like :xml and :json.
def api_behavior(error)
if get?
display resource
elsif has_errors?
@ -141,8 +153,6 @@ module ActionController #:nodoc:
end
end
protected
# Checks whether the resource responds to the current format or not.
#
def resourceful?
@ -194,7 +204,7 @@ module ActionController #:nodoc:
# the verb is post.
#
def default_action
request.post? ? :new : :edit
@action || (request.post? ? :new : :edit)
end
end
end

View file

@ -501,6 +501,12 @@ class RespondWithController < ActionController::Base
respond_with(Customer.new("david", 13), :responder => responder)
end
def using_resource_with_action
respond_with(Customer.new("david", 13), :action => :foo) do |format|
format.html { raise ActionView::MissingTemplate.new([], "method") }
end
end
protected
def _render_js(js, options)
@ -715,6 +721,20 @@ class RespondWithControllerTest < ActionController::TestCase
assert_match /<name>jamis<\/name>/, @response.body
end
def test_using_resource_with_action
@controller.instance_eval do
def render(params={})
self.response_body = "#{params[:action]} - #{formats}"
end
end
errors = { :name => :invalid }
Customer.any_instance.stubs(:errors).returns(errors)
post :using_resource_with_action
assert_equal "foo - #{[:html].to_s}", @controller.response_body
end
def test_clear_respond_to
@controller = InheritedRespondWithController.new
@request.accept = "text/html"
@ -760,7 +780,7 @@ class RespondWithControllerTest < ActionController::TestCase
assert_equal "Resource name is david", @response.body
end
def test_using_resource_with_responder
def test_using_resource_with_set_responder
RespondWithController.responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
get :using_resource
assert_equal "Resource name is david", @response.body