On 14 May 2012, at 03:08, Rodrigo Rosenfeld Rosas wrote:
> I would expect "render json: xxx" to render an 'application/json'
> content-type independent from the :format state. This is true for uncached
> actions but cached actions seems to only take into account the value of
> :format.
That's because the cache action tries to infer the format from the request but
can't because there's no extension or default value for :format. It sets the
content_type to the default HTML and when you call render :json it only sets
the content_type if it is not already been set.
I'm not sure what you expect Rails to do here - how does it know to fetch the
JSON cached version if you're relying on the content_type being set by the
render? The whole point of action caching is to avoid calling render.
> Because of that, we get a very verbose route for getting it to properly work
> with caches_action when we only want to support the :json format:
>
> get 'test/cached', format: false, defaults: {format: :json}
>
> That is the other inconsistency I was talking about. I'd prefer to just read
> the format option as the actual format instead of the default one like in:
>
> get 'test/cached', format: :json # that should be the same as the previous
> example for brevity
>
> but the above rule would allow '/test/cached.html' for instance. I find this
> an inconsistency with regards to API expected behavior, although it is
> consistent with the current implementation.
As I said non-regexp keys are assumed to be defaults - use a regexp to make it
only accept JSON:
get 'test/caches', :format => /json/
You'd need to have the format in the url though.
> Also, there is another problem. With this last rule, I'd need to append
> something like ", as: :test_cached" to be able to "expire_action
> :test_cached" since "expire_action action: :cached" won't work and the full
> line would be too lengthy: "expire_action action: :cached, format: :json".
As I said you may want to expire all or some cached action formats - not just
the format of the current request and you need to tell it which format somehow.
> Also, I don't understand why we have "caches_page" and "caches_action" but
> "expire_page" and "expire_action". For consistency sake those should be named
> either caches/expires or cache/expire...
It makes sense when you look at the tense - caches_action is saying that the
controller will cache the action (i.e in the future) whereas expire_action is
actually doing it now.
> Could you please give me an actual example where you find responds_to to be
> useful for applications that don't interact with external applications?
Pagination of results - use the JSON request to provide just the results so
that they can be rendered on the client.
> For example, if I have a '/products' and '/products.json' where the former
> will render an HTML that will fill the page with the products requested by
> the latter, I'd probably use separate actions as they do completely different
> things:
>
> get '/products' => 'products#index', format: false
> get '/products.json' => 'products#index_json', format: false, defaults:
> {format: :json}
class ProductsController
responds_to :html, :json
def index
@products = Products.paginate :page => params[:page]
responds_with(@products)
end
end
Then use something like Jbuilder or ActiveModel::Serializers to render the JSON
response and your standard ERb/Haml for the HTML response.
> If I understand correctly, this would require me to request
> '/test/expire.json', right? But usually I'd write the expire action with
> "head :ok", returning a 'text/html' or 'text/plain' instead of
> 'application/json'.
Sorry, I thought you wanted the expire action to return application/json.
>> You'll need to pass the format to the expire_action as it doesn't infer it
>> from the current request - otherwise you could only expire JSON caches from
>> JSON requests.
>
> Or I could just pass the named routes to "expire_action", right? The named
> route would already contain the format information so 'expire_action' method
> wouldn't need to guess.
Named url helpers still call url_for internally so you'd still end up with a
path without a format extension.
> That shortcoming could be minimized if we assumed the "format: :json" to
> restrict the only possible format to 'json' instead of using it as a default.
>
> Please consider this change to routing DSL for Rails 4.
We could certainly consider whether :format => :json or :format => [:html,
:json] would restrict it to those formats (i.e. setup :constraints and
:defaults automatically), however that would have to be with :format in the
path as you can't turn it off without :format => false. Please open an issue to
consider this further.
Andrew White
--
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Core" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.