どうにも、Railsのrespond_toメソッドがなんでこんな記述で動くのか良く判らなかったので、じっくり調べてみた。
def index
@books = Book.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @books }
end
end
lib\ruby\gems\1.9.1\gems\actionpack-3.1.0\lib\action_controller\metal\mime_responds.rb(42): def respond_to(*mimes) lib\ruby\gems\1.9.1\gems\actionpack-3.1.0\lib\action_controller\metal\mime_responds.rb(191): def respond_to(*mimes, &block)
include ActionController::ImplicitRender
included do
class_attribute :responder, :mimes_for_respond_to
self.responder = ActionController::Responder
clear_respond_to
end
module ClassMethods
def respond_to(*mimes)
options = mimes.extract_options!
only_actions = Array(options.delete(:only))
except_actions = Array(options.delete(:except))
new = mimes_for_respond_to.dup
mimes.each do |mime|
mime = mime.to_sym
new[mime] = {}
new[mime][:only] = only_actions unless only_actions.empty?
new[mime][:except] = except_actions unless except_actions.empty?
end
self.mimes_for_respond_to = new.freeze
end
def clear_respond_to
self.mimes_for_respond_to = ActiveSupport::OrderedHash.new.freeze
end
end
def respond_to(*mimes, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
if response = retrieve_response_from_mimes(mimes, &block)
response.call(nil)
end
end
def retrieve_response_from_mimes(mimes=nil, &block) #:nodoc:
mimes ||= collect_mimes_from_class_level
collector = Collector.new(mimes) { |options| default_render(options || {}) }
block.call(collector) if block_given?
if format = request.negotiate_mime(collector.order)
self.content_type ||= format.to_s
lookup_context.freeze_formats([format.to_sym])
collector.response_for(format)
else
head :not_acceptable
nil
end
end
def collect_mimes_from_class_level #:nodoc:
action = action_name.to_sym
self.class.mimes_for_respond_to.keys.select do |mime|
config = self.class.mimes_for_respond_to[mime]
if config[:except]
!action.in?(config[:except])
elsif config[:only]
action.in?(config[:only])
else
true
end
end
end
def foo(p1,p2,&block) block.call(p1,p2) end
foo("p1","p2") do |p1,p2|
p p1
p p2
end
"p1" "p2"
foo("p1","p2") do |p1,p2|
p p2
p p1
p "dummy"
end
"p2" "p1" "dummy"
mimes ||= collect_mimes_from_class_level