Em 14-05-2012 02:11, Andrew White escreveu:
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.

I was expecting the relevant headers to be cached alongside with the body content of the response.

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.

Well, this is great! I don't remember that you said that by using a regular expression it would be an enforcement instead of a default. And I don't mind that I have to use '/test/caches.json'. At least I know that if it is called in any other way the application will respond with 500 or any other error code.

Thank you very much!

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.

Ah, okay, I guess I got it now.

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.

So, shouldn't it be the opposite? Controller will *cache* and it currently *expires*? :)

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.

Okay, makes sense.

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.

Yeah, I had just figured it out from a previous comment of yours in this message :)

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.

Thanks! I'll try to figure it out an API that could allow an unformatted URL before opening the issue. If I can't come to any suggestion I'll open the issue with the API you've just mentioned.

Wouldn't it be possible that "get '/products', format: :json" responded to both '/products' and '/products.json' when a single format is given instead of an array? Of course I mean that action caching should also use the same correct content-type in the response for both URLs.

Cheers,
Rodrigo.

--
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.

Reply via email to