2011-07-16 4 views
20

tengo una ruta carriles que lleva símbolos ticker como: Identificación delNecesita una ruta rieles con un posible período en el: id, sino que también conservan la opción Formato

  • feeds/AMZN devolverá una página de Amazon
  • feeds/AMZN.csv devolverá una representación CSV de los mismos datos.

pero también necesito para dar cabida a acciones como VIA.B (Viacom), de modo que ambas rutas de trabajo:

feeds/VIA.B (html) 
feeds/VIA.B.csv (csv) 

Es esto posible? ¿Cómo podría configurar el enrutamiento?

Respuesta

30

Me encontré con esto mientras reparaba la API de RubyGems recientemente (tratando de acceder al flickr.rb usando la API (/api/v1/gems/flickr.rb.json) no funcionaba).

El truco era proporcionar la ruta con una expresión regular para manejar el parámetro :id, y luego especificar :format válido. Tenga en cuenta que la expresión regular :id debe ser "floja" (debe terminar con un signo de interrogación), de lo contrario, se comerá el .csv y supondrá que es parte de la identificación. El siguiente ejemplo permitiría JSON, CSV, XML y formatos YAML para un Id con un período en el que:

resources :feeds, :id => /[A-Za-z0-9\.]+?/, :format => /json|csv|xml|yaml/ 
+1

¿Qué sucede si también quiero incluir: identificadores con espacios en blanco, p. Ej./feeds/MI COMPAÑÍA? – dan

+3

No está permitido el espacio en blanco real, y creo que la mayoría de los navegadores reemplazarán el espacio en blanco con '% 20', por lo que solo necesita agregar'% 'a la expresión regular (también es más fácil usar el carácter de dígito/palabra matchers): '/ [\ w \ d%] +? /' –

+0

\ w y \ d se superponen https://ruby-doc.org/core-2.2.0/Regexp.html#class-Regexp-label -Character + Classes /\ d/- Un carácter de dígito ([0-9]) /\ w/- Un carácter de palabra ([a-zA-Z0-9_]) – bublik42

2

me encontré con esto también, pero en la dirección inversa. (url_for() produce "Sin coincidencias de ruta" solo para ID con. En ellos.)

Estoy usando match en lugar de resources para permitir que se munging. Si usted está haciendo lo mismo, esto es lo que el arreglo se parece a:

match "feeds/:id" => "stocks#feed", :constraints => {:id => /[\w.]+?/, :format => /html|csv/} 
8

vieja pregunta, pero he encontrado una manera mucho más simple que funciona con rutas anidadas (estoy on Rails 3.2.4). De esta manera, permite que todos los caracteres (incluido el punto) se opongan a la respuesta aceptada, lo que le permite especificar los caracteres permitidos.

resources :feeds, :id => /([^\/])+?/ 

nota de que había encontrado algunas otras sugerencias (por ejemplo aquí: http://coding-journal.com/rails-3-routing-parameters-with-dots/) de hacer algo como:

resources :feeds, :id => /.*/ 

pero eso no funcionó para mí con rutas anidadas por alguna razón.

+0

usando: id =>/([^ \ /]) +?/¡resolvió mi problema de punto también! wicked easy thxxx –

+1

En Rails 5+, es posible que deba eliminar el '?' para que la expresión regular no deje de capturar demasiado pronto. – jevon

Cuestiones relacionadas