提交 3f445b31 编写于 作者: J José Valim 提交者: Yehuda Katz

Refactor Responder to only calculate available mime types. Those are sent to...

Refactor Responder to only calculate available mime types. Those are sent to the controller that knows what to do with it (render a block or call default render).
Signed-off-by: NYehuda Katz <wycats@gmail.com>
上级 c4d1075b
module ActionController #:nodoc:
module MimeResponds #:nodoc:
# Without web-service support, an action which collects the data for displaying a list of people
# might look something like this:
#
......@@ -92,40 +93,39 @@ module MimeResponds #:nodoc:
# environment.rb as follows.
#
# Mime::Type.register "image/jpg", :jpg
def respond_to(*types, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
block ||= lambda { |responder| types.each { |type| responder.send(type) } }
responder = Responder.new(self)
block.call(responder)
responder.respond
end
class Responder #:nodoc:
def initialize(controller)
@controller = controller
@request = controller.request
@response = controller.response
def respond_to(*mimes, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" unless mimes.any? ^ block
@mime_type_priority = @request.formats
responder = Responder.new(request.formats)
@order = []
@responses = {}
if block_given?
block.call(responder)
else
mimes.each { |mime| responder.send(mime) }
end
def custom(mime_type, &block)
mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
@order << mime_type
mime = responder.respond
@responses[mime_type] ||= Proc.new do
# TODO: Remove this when new base is merged in
@controller.formats = [mime_type.to_sym]
@controller.content_type = mime_type
@controller.template.formats = [mime_type.to_sym]
if mime
self.formats = [mime.to_sym]
self.content_type = mime
self.template.formats = [mime.to_sym]
block_given? ? block.call : @controller.send(:render, :action => @controller.action_name)
if response = responder.response_for(mime)
response.call
else
default_render
end
else
head :not_acceptable
end
end
class Responder #:nodoc:
def initialize(priorities)
@mime_type_priority = priorities
@order, @responses = [], {}
end
def any(*args, &block)
......@@ -135,51 +135,64 @@ def any(*args, &block)
custom(@mime_type_priority.first, &block)
end
end
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.to_s.upcase
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{sym}(&block) # def html(&block)
custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
end # end
RUBY
def custom(mime_type, &block)
mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
@order << mime_type
@responses[mime_type] ||= block
end
Mime::SET.each do |mime|
generate_method_for_mime(mime)
def respond
available_mimes.first
end
def response_for(mime)
@responses[mime]
end
# Compares mimes sent by the client (@mime_type_priorities) with the ones
# that the user configured in the controller respond_to. Returns them
# all in an array.
#
def available_mimes
mimes = []
@mime_type_priority.each do |priority|
if priority == Mime::ALL
mimes << @order.first unless mimes.include?(@order.first)
elsif @order.include?(priority)
mimes << priority
end
end
mimes << Mime::ALL if @order.include?(Mime::ALL)
mimes
end
protected
def method_missing(symbol, &block)
mime_constant = Mime.const_get(symbol.to_s.upcase)
if Mime::SET.include?(mime_constant)
self.class.generate_method_for_mime(mime_constant)
generate_method_for_mime(mime_constant)
send(symbol, &block)
else
super
end
end
def respond
for priority in @mime_type_priority
if priority == Mime::ALL
@responses[@order.first].call
return
else
if @responses[priority]
@responses[priority].call
return # mime type match found, be happy and return
end
end
end
if @order.include?(Mime::ALL)
@responses[Mime::ALL].call
else
@controller.send :head, :not_acceptable
end
def generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.to_s.upcase
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{sym}(&block) # def html(&block)
custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
end # end
RUBY
end
end
end
end
......@@ -436,9 +436,9 @@ def test_extension_synonyms
def test_render_action_for_html
@controller.instance_eval do
def render(*args)
unless args.empty?
@action = args.first[:action] || action_name
end
@action = args.first[:action] unless args.empty?
@action ||= action_name
response.body = "#{@action} - #{@template.formats}"
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册