Nombre y valor del parámetro (de forma independiente) como parte de Rails Route

StackOverflow https://stackoverflow.com/questions/339706

  •  19-08-2019
  •  | 
  •  

Pregunta

DocumentsController # common_query puede manejar múltiples estilos de solicitud diferentes.

es decir todos los documentos en el lote 4 o todos los documentos etiquetados como "feliz"

Quiero una sola ruta para hacerlos bonitos, así que:

/ documents / common_query? batch = 4

/ documents / common_query? tag = happy

convertirse en:

/ documentos / lote / 4

/ documents / tag / happy

Entonces, el resultado final es que se llama a #common_query pero parte de la url se usó como el nombre del parámetro y parte como su valor.

¿Fue útil?

Solución

Como una ruta única:

ActionController::Routing::Routes.draw do |map|
  map.connect "documents/:type/:id", :controller => "documents_controller", 
              :action => "common_query"
end

Entonces params [: type] será " batch " o " tag " , y params [: id] ya sea " 4 " o " happy " . Tendrá que asegurarse de que otras acciones para el DocumentsController vengan antes de esto en las rutas porque esto coincidirá con cualquier URL que se vea como " documents / * / * " .

Pero, ¿por qué tiene que ser una ruta única? Podría usar dos rutas como esta:

map.with_options(:controller => "documents_controller", 
                 :action => "common_query") do |c|
  c.connect "documents/batch/:page", :type => "batch"
  c.connect "documents/tag/:tag",    :type => "tag"
end

que tendrá el mismo efecto, pero es más específico, para que no tenga que preocuparse por el orden de prioridad de las rutas.

Otros consejos

La segunda opción, con dos rutas, es casi con certeza la mejor opción, ya que solo coincidirá con los tipos de URL que desea admitir, mientras que la primera opción también "coincidirá". URL como / documents / foo / bar, lo que probablemente hará que su método #common_query devuelva, en el mejor de los casos, una respuesta RecordNotFound (404). En el peor de los casos, si no está listo para no ver ninguno de sus parámetros esperados, obtendrá un error 500 en su lugar ...

Por supuesto, si comienzas a tener muchas variaciones, terminas con muchas rutas. Y si necesita usarlos en combinación, por ejemplo, / documentos / lote / 4 / etiqueta / feliz, entonces deberá usar una ruta comodín y realizar el procesamiento de parámetros en su controlador. Esto podría verse más o menos así:

map.connect 'documents/*specs', :controller => "documents_controller", :action => "common_query"

Los diversos elementos de la URL estarán disponibles en su controlador como parámetros [: especificaciones]. Puede convertir eso en un hallazgo así:

@items = Item.find(:all, :conditions => Hash[params[:specs]])

Esa técnica Hash [] convierte la matriz unidimensional de opciones en un hash de valor clave, lo que podría ser útil incluso si no lo está alimentando directamente a find ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top