From 7afb7ed0aff74a5ee27bbc106ff732c4f21d4eec Mon Sep 17 00:00:00 2001 From: David Knorr Date: Thu, 23 Apr 2009 15:22:17 +0200 Subject: [PATCH] Added the ability to specify a single responder for multiple types in order to DRY up the respond_to block respond_to do |format| format.html { @posts = Post.find(:all, :limit => 10) } format.rss_and_atom { @posts = Post.find(:all) } end --- .../lib/action_controller/base/mime_responds.rb | 39 +++++++++++++++++--- actionpack/test/controller/mime_responds_test.rb | 13 +++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb index bac225a..6f9cd9d 100644 --- a/actionpack/lib/action_controller/base/mime_responds.rb +++ b/actionpack/lib/action_controller/base/mime_responds.rb @@ -99,6 +99,18 @@ module ActionController #:nodoc: # environment.rb as follows. # # Mime::Type.register "image/jpg", :jpg + # + # In order to DRY things up, you can specify one thing to do for multiple MIME types in the same block: + # + # def index + # respond_to do |format| + # format.html { @posts = Post.find(:all, :limit => 10) } + # format.rss_and_atom { @posts = Post.find(:all) } + # end + # end + # + # In this case we only want to display ten posts on the HTML version of our index action. But when the user + # requests either the RSS or Atom format of the same action, we simply want to display all available posts. 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) } } @@ -156,13 +168,28 @@ module ActionController #:nodoc: end 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) - send(symbol, &block) + if symbol.to_s.include?("_and_") + mimes = symbol.to_s.split("_and_") + + mimes.each do |mime| + mime_constant = Mime.const_get(mime.upcase) + + if Mime::SET.include?(mime_constant) + self.class.generate_method_for_mime(mime_constant) + send(mime, &block) + else + super + end + end else - super + mime_constant = Mime.const_get(symbol.to_s.upcase) + + if Mime::SET.include?(mime_constant) + self.class.generate_method_for_mime(mime_constant) + send(symbol, &block) + else + super + end end end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 7cd5145..402b1c8 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -148,6 +148,12 @@ class RespondToController < ActionController::Base Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) } end + def rss_or_atom_in_same_responder + respond_to do |type| + type.rss_and_atom { render :text => 'RSS and Atom' } + end + end + def rescue_action(e) raise end @@ -473,6 +479,13 @@ class MimeControllerTest < ActionController::TestCase @request.accept = "text/iphone" assert_raise(ActionView::MissingTemplate) { get :iphone_with_html_response_type_without_layout } end + + def test_rss_and_atom_in_same_responder + [:rss, :atom].each do |format| + get :rss_or_atom_in_same_responder, :format => format + assert_equal 'RSS and Atom', @response.body + end + end end class AbstractPostController < ActionController::Base -- 1.5.6.3