Skip to content
This repository
Newer
Older
100644 324 lines (300 sloc) 10.911 kb
ddfc0725 » José Valim and Mikel Lindsaar
2010-01-23 Added AbstractController::Collector.
1 require 'abstract_controller/collector'
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
2 require 'active_support/core_ext/class/attribute'
a9f3c9da » sikachu
2011-04-11 Using Object#in? and Object#either? in various places
3 require 'active_support/core_ext/object/inclusion'
ddfc0725 » José Valim and Mikel Lindsaar
2010-01-23 Added AbstractController::Collector.
4
1c16649b » dhh
2006-03-11 Added better support for using the same actions to output for differe…
5 module ActionController #:nodoc:
c59456a1 » joliss
2011-04-08 removed :nodoc: from ActionController::MimeResponds
6 module MimeResponds
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
7 extend ActiveSupport::Concern
8
944b4d57 » josevalim
2011-04-18 Add missing dependency.
9 include ActionController::ImplicitRender
10
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
11 included do
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
12 class_attribute :responder, :mimes_for_respond_to
2e37effd » josevalim
2009-10-17 Unify class_inheritable_accessor and extlib_inheritable_accessor and …
13 self.responder = ActionController::Responder
fa0cf663 » josevalim
2009-07-29 Add a couple more tests to respond_with.
14 clear_respond_to
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
15 end
16
17 module ClassMethods
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
18 # Defines mime types that are rendered by default when invoking
19 # <tt>respond_with</tt>.
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
20 #
21 # Examples:
22 #
23 # respond_to :html, :xml, :json
24 #
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
25 # Specifies that all actions in the controller respond to requests
26 # for <tt>:html</tt>, <tt>:xml</tt> and <tt>:json</tt>.
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
27 #
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
28 # To specify on per-action basis, use <tt>:only</tt> and
29 # <tt>:except</tt> with an array of actions or a single action:
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
30 #
31 # respond_to :html
32 # respond_to :xml, :json, :except => [ :edit ]
33 #
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
34 # This specifies that all actions respond to <tt>:html</tt>
35 # and all actions except <tt>:edit</tt> respond to <tt>:xml</tt> and
36 # <tt>:json</tt>.
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
37 #
5850f169 » fxn
2011-03-25 removes the RJS template handler
38 # respond_to :json, :only => :create
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
39 #
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
40 # This specifies that the <tt>:create</tt> action and no other responds
5850f169 » fxn
2011-03-25 removes the RJS template handler
41 # to <tt>:json</tt>.
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
42 def respond_to(*mimes)
43 options = mimes.extract_options!
44
50d262f5 » avakhov
2011-10-11 Support symbol and string actions in AC#respond_to options
45 only_actions = Array(options.delete(:only)).map(&:to_s)
46 except_actions = Array(options.delete(:except)).map(&:to_s)
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
47
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
48 new = mimes_for_respond_to.dup
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
49 mimes.each do |mime|
50 mime = mime.to_sym
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
51 new[mime] = {}
52 new[mime][:only] = only_actions unless only_actions.empty?
53 new[mime][:except] = except_actions unless except_actions.empty?
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
54 end
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
55 self.mimes_for_respond_to = new.freeze
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
56 end
57
79f9fcd7 » wincent
2010-07-26 doc: cleanup respond_to documentation
58 # Clear all mime types in <tt>respond_to</tt>.
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
59 #
fa0cf663 » josevalim
2009-07-29 Add a couple more tests to respond_with.
60 def clear_respond_to
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
61 self.mimes_for_respond_to = ActiveSupport::OrderedHash.new.freeze
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
62 end
63 end
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
64
01f032f2 » Yehuda Katz + Carl Lerche
2009-05-20 Added responds_to to new base.
65 # Without web-service support, an action which collects the data for displaying a list of people
66 # might look something like this:
67 #
68 # def index
1a6c4c86 » willcannings
2010-12-19 Correct deprecated AR usage in ActionController::MimeResponds documen…
69 # @people = Person.all
01f032f2 » Yehuda Katz + Carl Lerche
2009-05-20 Added responds_to to new base.
70 # end
71 #
72 # Here's the same action, with web-service support baked in:
73 #
74 # def index
1a6c4c86 » willcannings
2010-12-19 Correct deprecated AR usage in ActionController::MimeResponds documen…
75 # @people = Person.all
01f032f2 » Yehuda Katz + Carl Lerche
2009-05-20 Added responds_to to new base.
76 #
77 # respond_to do |format|
78 # format.html
79 # format.xml { render :xml => @people.to_xml }
80 # end
81 # end
82 #
83 # What that says is, "if the client wants HTML in response to this action, just respond as we
84 # would have before, but if the client wants XML, return them the list of people in XML format."
85 # (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
86 #
87 # Supposing you have an action that adds a new person, optionally creating their company
88 # (by name) if it does not already exist, without web-services, it might look like this:
89 #
90 # def create
91 # @company = Company.find_or_create_by_name(params[:company][:name])
92 # @person = @company.people.create(params[:person])
93 #
94 # redirect_to(person_list_url)
95 # end
96 #
97 # Here's the same action, with web-service support baked in:
98 #
99 # def create
100 # company = params[:person].delete(:company)
101 # @company = Company.find_or_create_by_name(company[:name])
102 # @person = @company.people.create(params[:person])
103 #
104 # respond_to do |format|
105 # format.html { redirect_to(person_list_url) }
106 # format.js
107 # format.xml { render :xml => @person.to_xml(:include => @company) }
108 # end
109 # end
110 #
5850f169 » fxn
2011-03-25 removes the RJS template handler
111 # If the client wants HTML, we just redirect them back to the person list. If they want JavaScript,
112 # then it is an Ajax request and we render the JavaScript template associated with this action.
01f032f2 » Yehuda Katz + Carl Lerche
2009-05-20 Added responds_to to new base.
113 # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also
114 # include the person's company in the rendered XML, so you get something like this:
115 #
116 # <person>
117 # <id>...</id>
118 # ...
119 # <company>
120 # <id>...</id>
121 # <name>...</name>
122 # ...
123 # </company>
124 # </person>
125 #
126 # Note, however, the extra bit at the top of that action:
127 #
128 # company = params[:person].delete(:company)
129 # @company = Company.find_or_create_by_name(company[:name])
130 #
131 # This is because the incoming XML document (if a web-service request is in process) can only contain a
132 # single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):
133 #
134 # person[name]=...&person[company][name]=...&...
135 #
136 # And, like this (xml-encoded):
137 #
138 # <person>
139 # <name>...</name>
140 # <company>
141 # <name>...</name>
142 # </company>
143 # </person>
144 #
145 # In other words, we make the request so that it operates on a single entity's person. Then, in the action,
146 # we extract the company data from the request, find or create the company, and then create the new person
147 # with the remaining data.
148 #
149 # Note that you can define your own XML parameter parser which would allow you to describe multiple entities
150 # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow
151 # and accept Rails' defaults, life will be much easier.
152 #
153 # If you need to use a MIME type which isn't supported by default, you can register your own handlers in
7e075e62 » Benjamin Quorning
2010-07-09 Fixed many references to the old config/environment.rb and Rails::Ini…
154 # config/initializers/mime_types.rb as follows.
01f032f2 » Yehuda Katz + Carl Lerche
2009-05-20 Added responds_to to new base.
155 #
156 # Mime::Type.register "image/jpg", :jpg
09de34ca » josevalim
2009-07-29 Added respond_with.
157 #
158 # Respond to also allows you to specify a common block for different formats by using any:
159 #
160 # def index
1a6c4c86 » willcannings
2010-12-19 Correct deprecated AR usage in ActionController::MimeResponds documen…
161 # @people = Person.all
09de34ca » josevalim
2009-07-29 Added respond_with.
162 #
163 # respond_to do |format|
164 # format.html
165 # format.any(:xml, :json) { render request.format.to_sym => @people }
166 # end
167 # end
168 #
169 # In the example above, if the format is xml, it will render:
170 #
171 # render :xml => @people
172 #
173 # Or if the format is json:
174 #
175 # render :json => @people
176 #
177 # Since this is a common pattern, you can use the class method respond_to
178 # with the respond_with method to have the same results:
179 #
180 # class PeopleController < ApplicationController
181 # respond_to :html, :xml, :json
182 #
183 # def index
1a6c4c86 » willcannings
2010-12-19 Correct deprecated AR usage in ActionController::MimeResponds documen…
184 # @people = Person.all
6ac56ac9 » vijaydev
2011-11-07 fix incorrect code example
185 # respond_with(@people)
09de34ca » josevalim
2009-07-29 Added respond_with.
186 # end
187 # end
188 #
189 # Be sure to check respond_with and respond_to documentation for more examples.
190 #
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
191 def respond_to(*mimes, &block)
67b2d08c » josevalim
2009-07-29 Ensure that the proper accept header value is set during tests.
192 raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
3f78de67 » josevalim
2009-08-29 Ensure that blocks are also handled inside the responder.
193
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
194 if collector = retrieve_collector_from_mimes(mimes, &block)
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
195 response = collector.response
196 response ? response.call : default_render({})
3f78de67 » josevalim
2009-08-29 Ensure that blocks are also handled inside the responder.
197 end
09de34ca » josevalim
2009-07-29 Added respond_with.
198 end
672941de » jeremy
2007-05-26 Introduce a default respond_to block for custom types. Closes #8174.
199
6e0ac748 » josevalim
2009-08-08 Renamed ActionController::Renderer to ActionController::Responder and…
200 # respond_with wraps a resource around a responder for default representation.
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
201 # First it invokes respond_to, if a response cannot be found (ie. no block
202 # for the request was given and template was not available), it instantiates
6e0ac748 » josevalim
2009-08-08 Renamed ActionController::Renderer to ActionController::Responder and…
203 # an ActionController::Responder with the controller and resource.
5b7e81ef » josevalim
2009-07-31 Allow respond_with to deal with http verb accordingly.
204 #
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
205 # ==== Example
5b7e81ef » josevalim
2009-07-31 Allow respond_with to deal with http verb accordingly.
206 #
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
207 # def index
208 # @users = User.all
209 # respond_with(@users)
09de34ca » josevalim
2009-07-29 Added respond_with.
210 # end
211 #
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
212 # It also accepts a block to be given. It's used to overwrite a default
213 # response:
f59984cc » josevalim
2009-08-01 Add nagivational behavior to respond_with.
214 #
aebbbc78 » willcannings
2010-12-19 Fix respond_with example code so it makes sense
215 # def create
216 # @user = User.new(params[:user])
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
217 # flash[:notice] = "User was successfully created." if @user.save
5b7e81ef » josevalim
2009-07-31 Allow respond_with to deal with http verb accordingly.
218 #
1fd65c80 » josevalim
2009-08-05 Encapsulate respond_with behavior in a presenter.
219 # respond_with(@user) do |format|
220 # format.html { render }
221 # end
70342723 » josevalim
2009-08-01 Add destroyed? to ActiveRecord, include tests for polymorphic urls fo…
222 # end
223 #
6e0ac748 » josevalim
2009-08-08 Renamed ActionController::Renderer to ActionController::Responder and…
224 # All options given to respond_with are sent to the underlying responder,
225 # except for the option :responder itself. Since the responder interface
aed135d3 » josevalim
2009-08-06 Renamed presenter to renderer, added some documentation and defined i…
226 # is quite simple (it just needs to respond to call), you can even give
227 # a proc to it.
70342723 » josevalim
2009-08-01 Add destroyed? to ActiveRecord, include tests for polymorphic urls fo…
228 #
a64abdda » amaia
2011-03-31 Explain in the method doc that you need to call respond_to at the cla…
229 # In order to use respond_with, first you need to declare the formats your
230 # controller responds to in the class level with a call to <tt>respond_to</tt>.
231 #
4f9047ec » josevalim
2009-08-13 Ensure collections are not treated as nested resources.
232 def respond_with(*resources, &block)
d2e7c1b9 » josevalim
2010-01-10 Raise an error if respond_with is invoked and no format is declared.
233 raise "In order to use respond_with, first you need to declare the formats your " <<
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
234 "controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
d2e7c1b9 » josevalim
2010-01-10 Raise an error if respond_with is invoked and no format is declared.
235
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
236 if collector = retrieve_collector_from_mimes(&block)
b1667c7c » chriseppstein
2010-11-05 Correctly handle the case of an API response that returns a hash by t…
237 options = resources.size == 1 ? {} : resources.extract_options!
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
238
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
239 if defined_response = collector.response
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
240 if action = options.delete(:action)
241 render :action => action
242 else
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
243 defined_response.call
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
244 end
245 else
246 (options.delete(:responder) || self.class.responder).call(self, resources, options)
247 end
684a6b3c » josevalim
2009-08-29 Attempt to render the template inside the responder, so it can be use…
248 end
aed135d3 » josevalim
2009-08-06 Renamed presenter to renderer, added some documentation and defined i…
249 end
7a4a679d » josevalim
2009-07-30 Remove any resource logic from respond_to.
250
251 protected
252
09de34ca » josevalim
2009-07-29 Added respond_with.
253 # Collect mimes declared in the class method respond_to valid for the
254 # current action.
255 #
256 def collect_mimes_from_class_level #:nodoc:
50d262f5 » avakhov
2011-10-11 Support symbol and string actions in AC#respond_to options
257 action = action_name.to_s
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
258
e5ab4b0d » jeremy
2010-01-31 Convert to class_attribute
259 self.class.mimes_for_respond_to.keys.select do |mime|
260 config = self.class.mimes_for_respond_to[mime]
09de34ca » josevalim
2009-07-29 Added respond_with.
261
262 if config[:except]
a9f3c9da » sikachu
2011-04-11 Using Object#in? and Object#either? in various places
263 !action.in?(config[:except])
09de34ca » josevalim
2009-07-29 Added respond_with.
264 elsif config[:only]
a9f3c9da » sikachu
2011-04-11 Using Object#in? and Object#either? in various places
265 action.in?(config[:only])
09de34ca » josevalim
2009-07-29 Added respond_with.
266 else
267 true
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
268 end
269 end
09de34ca » josevalim
2009-07-29 Added respond_with.
270 end
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
271
3f78de67 » josevalim
2009-08-29 Ensure that blocks are also handled inside the responder.
272 # Collects mimes and return the response for the negotiated format. Returns
273 # nil if :not_acceptable was sent to the client.
684a6b3c » josevalim
2009-08-29 Attempt to render the template inside the responder, so it can be use…
274 #
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
275 def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
d2e7c1b9 » josevalim
2010-01-10 Raise an error if respond_with is invoked and no format is declared.
276 mimes ||= collect_mimes_from_class_level
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
277 collector = Collector.new(mimes)
3f78de67 » josevalim
2009-08-29 Ensure that blocks are also handled inside the responder.
278 block.call(collector) if block_given?
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
279 format = collector.negotiate_format(request)
684a6b3c » josevalim
2009-08-29 Attempt to render the template inside the responder, so it can be use…
280
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
281 if format
f2c0a353 » josevalim
2010-03-12 Finish cleaning up rendering stack from views and move assigns evalua…
282 self.content_type ||= format.to_s
a09e9925 » josevalim
2010-03-27 Ensure details are frozen after @details_keys lookup. The implementat…
283 lookup_context.freeze_formats([format.to_sym])
567ac65b » sikachu
2012-02-03 Fix override API response bug in respond_with
284 collector
684a6b3c » josevalim
2009-08-29 Attempt to render the template inside the responder, so it can be use…
285 else
286 head :not_acceptable
3f78de67 » josevalim
2009-08-29 Ensure that blocks are also handled inside the responder.
287 nil
684a6b3c » josevalim
2009-08-29 Attempt to render the template inside the responder, so it can be use…
288 end
289 end
290
6e0ac748 » josevalim
2009-08-08 Renamed ActionController::Renderer to ActionController::Responder and…
291 class Collector #:nodoc:
ddfc0725 » José Valim and Mikel Lindsaar
2010-01-23 Added AbstractController::Collector.
292 include AbstractController::Collector
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
293 attr_accessor :order, :format
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
294
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
295 def initialize(mimes)
296 @order, @responses = [], {}
74049b57 » spastorino
2010-11-25 implicit self here
297 mimes.each { |mime| send(mime) }
7af12d04 » dhh
2006-03-12 Added synonym and custom type handling to respond_to [DHH]
298 end
6480d497 » jamis
2006-03-15 Add MimeResponds::Responder#any for managing multiple types with iden…
299
300 def any(*args, &block)
011e4694 » lifo
2008-03-07 Make MimeResponds::Responder#any work without explicit types. Closes #…
301 if args.any?
302 args.each { |type| send(type, &block) }
303 else
3e8ba616 » josevalim
2009-07-28 Refactor even more Responder. Move mime negotiation to request and ad…
304 custom(Mime::ALL, &block)
011e4694 » lifo
2008-03-07 Make MimeResponds::Responder#any work without explicit types. Closes #…
305 end
6dea52c5 » dhh
2006-06-02 Finish custom handling [DHH]
306 end
7e280c3b » josevalim
2009-07-29 Remove Mime::ALL from Mime::SET.
307 alias :all :any
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
308
309 def custom(mime_type, &block)
6e559168 » spastorino
2010-11-22 There's no need for ternary op here
310 mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
311 @order << mime_type
312 @responses[mime_type] ||= block
6dc12881 » wycats
2008-12-26 Remove method missing use in respond_to
313 end
672941de » jeremy
2007-05-26 Introduce a default respond_to block for custom types. Closes #8174.
314
2bf2055f » josevalim
2012-02-04 Clean up a bit default_response handling and cache format negotiation.
315 def response
316 @responses[format] || @responses[Mime::ALL]
317 end
318
319 def negotiate_format(request)
320 @format = request.negotiate_mime(order)
3f445b31 » josevalim
2009-07-28 Refactor Responder to only calculate available mime types. Those are …
321 end
1c16649b » dhh
2006-03-11 Added better support for using the same actions to output for differe…
322 end
323 end
0ee1cb2c » jeremy
2007-10-02 Ruby 1.9 compat, consistent load paths
324 end
Something went wrong with that request. Please try again.