2011-05-13 17 views
6

Tengo una API basada en JSON y XML que debe almacenarse en la página. He fijado mis rutas en el API para incluir el formato como parte de la URL, de manera que la dirección URL de esta manera el trabajo:Problema con el almacenamiento en caché de la página Rails y extensiones automáticas

http://example.com/foo/1/bar/2/xml 
http://example.com/foo/1/bar/2/json 

El problema que veo es que en la carpeta del servidor de public, los archivos se guardan como xml.xml y json.json, y esto causa que el caché omita la próxima vez que se accede a la URL.

¿Hay una manera de cualquiera:

  1. Apague la generación automática de extensión para que se guardan sin una extensión en absoluto? (EX: RAILS_ROOT/public/foo/1/bar/2/json)
  2. Fuerce todas las extensiones para que sean .html para cada llamada. (EX: RAILS_ROOT/public/foo/1/bar/2/json.html)

Cualquiera de estos haría que mi servidor devuelva el archivo en caché en lugar de perderse. ¿Cómo puedo hacer esto?

EDIT:
Alguien le preguntó por la ruta relevante:

scope '(foo/:foo_id)', :foo_id => /\d+/ do 
    get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/ 
end 



SOLUCIÓN:
Mientras yo estaba buscando una manera oficial para que esto suceda utilizando el construido en la página apoyo para el almacenamiento en caché, terminé simplemente usando un filtro posterior y mi propio método de caché de página, según lo sugerido por Anton

# application_controller.rb 
def cache_api_page 
    if REDACTEDServer::Application.config.action_controller.perform_caching 
    self.class.cache_page(response.body, request.path, '') 
    puts "CACHED PATH: #{request.path}" 
    end 
end 

# bar_controller.rb 
after_filter :cache_api_page, :only => [ :show, :index ] 
+0

¿Has probado la convención "normal" en la API, a partir de ..bar/2.xml y ../bar/2.json? – oma

+0

Este no es el diseño de la API y necesito que sea compatible con versiones anteriores, por lo que no puedo cambiar al método .ext. En mi humilde opinión, hace urls feos. – coneybeare

+0

¿Puedes publicar una muestra de tus rutas? –

Respuesta

3

puede hacerlo de esta manera:

class FooController < ApplicationController 

    after_filter(:only => :show, :if => Proc.new { |c| c.request.format.json? }) do |controller| 
    controller.class.cache_page(controller.response.body, controller.request.path, '.html') 
    end 

end 

cuando se accede a http://example.com/foo/1/bar/2/json, escribirá la página de caché (RAILS_ROOT/public/foo/1/bar/2/json.html)

Y si obtiene http://example.com/foo/1/bar/2/json nuevamente, recibirá RAILS_ROOT/public/foo/1/bar/2/json.html, pero su servidor http (Apache?) Debería conocer el tipo de contenido de estos archivos.

Tipo De lo contrario contenido será puesto a 'text/html'

ACTUALIZACIÓN

Para .htaccess

<FilesMatch "\/json$"> 
<IfModule mod_headers.c> 
    Header set Content-Type "text/json" 
</IfModule> 
</FilesMatch> 


<FilesMatch "\/xml$"> 
<IfModule mod_headers.c> 
    Header set Content-Type "text/xml" 
</IfModule> 
</FilesMatch> 
+0

Parece que podría funcionar, pero requiere una gran cantidad de código escrito en mi aplicación y mis métodos. Esperaré a darte la respuesta hasta que vea qué más entra. Con respecto a Apache, las solicitudes vienen exactamente igual que la URL listada anteriormente, por lo tanto, Apache no sabe que es un archivo xml o json a menos que haga que las solicitudes tengan una extensión .xml o .json. Es por eso que necesito hacer esto. – coneybeare

+0

Debe agregar .htaccess ... ver la actualización – Anton

+0

Su actualización no funcionará en los rieles porque htaccess se ignora con los carriles, las configuraciones de apache de los pasajeros. Tu respuesta inicial aún es válida – coneybeare

0

En su application.rb bloque de configuración intento de añadir:

config.action_controller.page_cache_extension = '.html' 

Debe ignorar la e xtensión calculada a partir de la solicitud, y siempre use esto. También podría intentar usar esto con una cadena vacía en su lugar.

EDIT: en realidad esto no funcionará porque esto solo establece un valor predeterminado.Si la solicitud tiene una extensión (en su caso, que concluyó de: formato) se usará.

Sugiero cambiar: formatee en sus rutas a otra cosa, que los rieles no den un significado especial a, como: fmt. Entonces los rieles no deberían agregar la extensión y el valor predeterminado a '.html'.

Edit2: Si usted tiene que utilizar: formato que puede monkeypatch Rieles:

ActionController::Caching::Pages::ClassMethods 
    private 
    def page_cache_file(path) 
    name = (path.empty? || path == "/") ? "/index" : URI.unescape(path.chomp('/')) 
    name << page_cache_extension #unless (name.split('/').last || name).include? '.' 
    return name 
    end 
end 

Aviso el signo de comentarios que he añadido antes 'a menos'. Esta es la parte que anula el valor predeterminado de mi primera respuesta.

Cuestiones relacionadas