2011-01-15 30 views
15

Tengo problemas para encaminar un formulario para una acción personalizada en Rails 3. Éstos son mis rutas:Rails 3 Formulario para la acción personalizada

resources :photos do 
    resources :comments 
    collection do 
     get 'update_states' 
    end 
    member do 
     put 'upload' 
    end 
end 

Aquí está la form_for:

form_for @photo, :remote => true, :url => { :action => upload_photo_path(@photo) }, :html => { :multipart => :true, :method => 'put' } do |f| 

Y es aquí el mensaje de error:

No route matches {:action=>"/photos/42/upload", :controller=>"photos"} 

... esto es especialmente frustrante porque "fotos /: id/carga" es exactamente la acción correcta para este formulario.

¿Qué me estoy perdiendo?

EDITS - Aquí están las rutas originales relacionados con la fotografía:

photo_comments GET /photos/:photo_id/comments(.:format)   {:action=>"index", :controller=>"comments"} 
        POST /photos/:photo_id/comments(.:format)   {:action=>"create", :controller=>"comments"} 
    new_photo_comment GET /photos/:photo_id/comments/new(.:format)  {:action=>"new", :controller=>"comments"} 
    edit_photo_comment GET /photos/:photo_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"} 
     photo_comment GET /photos/:photo_id/comments/:id(.:format)  {:action=>"show", :controller=>"comments"} 
        PUT /photos/:photo_id/comments/:id(.:format)  {:action=>"update", :controller=>"comments"} 
        DELETE /photos/:photo_id/comments/:id(.:format)  {:action=>"destroy", :controller=>"comments"} 
update_states_photos GET /photos/update_states(.:format)    {:action=>"update_states", :controller=>"photos"} 
     upload_photo PUT /photos/:id/upload(.:format)     {:action=>"upload", :controller=>"photos"} 
       photos GET /photos(.:format)        {:action=>"index", :controller=>"photos"} 
        POST /photos(.:format)        {:action=>"create", :controller=>"photos"} 
      new_photo GET /photos/new(.:format)       {:action=>"new", :controller=>"photos"} 
      edit_photo GET /photos/:id/edit(.:format)     {:action=>"edit", :controller=>"photos"} 
       photo GET /photos/:id(.:format)       {:action=>"show", :controller=>"photos"} 
        PUT /photos/:id(.:format)       {:action=>"update", :controller=>"photos"} 
        DELETE /photos/:id(.:format)       {:action=>"destroy", :controller=>"photos"} 

Estas son las rutas pertinentes cuando cambié la ruta a match 'upload':

photo_comments GET /photos/:photo_id/comments(.:format)   {:action=>"index", :controller=>"comments"} 
        POST /photos/:photo_id/comments(.:format)   {:action=>"create", :controller=>"comments"} 
} 
    new_photo_comment GET /photos/:photo_id/comments/new(.:format)  {:action=>"new", :controller=>"comments"} 
    edit_photo_comment GET /photos/:photo_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"} 
     photo_comment GET /photos/:photo_id/comments/:id(.:format)  {:action=>"show", :controller=>"comments"} 
        PUT /photos/:photo_id/comments/:id(.:format)  {:action=>"update", :controller=>"comments"} 
        DELETE /photos/:photo_id/comments/:id(.:format)  {:action=>"destroy", :controller=>"comments"} 
update_states_photos GET /photos/update_states(.:format)    {:action=>"update_states", :controller=>"photos"} 
     upload_photo  /photos/:id/upload(.:format)     {:action=>"upload", :controller=>"photos"} 
       photos GET /photos(.:format)        {:action=>"index", :controller=>"photos"} 
        POST /photos(.:format)        {:action=>"create", :controller=>"photos"} 
      new_photo GET /photos/new(.:format)       {:action=>"new", :controller=>"photos"} 
      edit_photo GET /photos/:id/edit(.:format)     {:action=>"edit", :controller=>"photos"} 
       photo GET /photos/:id(.:format)       {:action=>"show", :controller=>"photos"} 
        PUT /photos/:id(.:format)       {:action=>"update", :controller=>"photos"} 
        DELETE /photos/:id(.:format)       {:action=>"destroy", :controller=>"photos"} 

desgracia 'partido' no funcionó mejor ...

- EDITAR -

Sólo para confirmar otro escenario aquí ... con esto en las rutas:

resources :photos do 
    resources :comments 
    collection do 
     get 'update_states' 
    end 
    member do 
     match 'upload' 
    end 
end 

y esto a la vista:

form_for @photo, :remote => true, :url => { :action => 'upload' }, :html => { :multipart => :true, :id => 'photo_upload' } do |f|

todavía me sale:

No route matches {:action=>"upload", :controller=>"photos"}

Respuesta

27

¿Qué pasa si solo :url => upload_photo_path(@photo)?

Parece un poco extraño que usted esté cargando a un miembro. ¿Es esto solo un método de creación (en cuyo caso debes simplemente enviar a la ruta de recolección)?

+0

Puedo intentarlo más tarde, pero he decidido ir en una dirección completamente nueva. La razón para subir archivos a un miembro es que estaba creando, preparando y guardando cuando el usuario hace clic en 'nuevo', y en realidad están editando el registro a medida que completan la información por primera vez. Hice esto porque quiero poder guardar su progreso a medida que avanzan, y hay varios modelos asociados que necesitan el ID padre para guardar correctamente ... de todos modos, esto era demasiado doloroso, así que estoy intentando para llegar a un nuevo enfoque por completo. – Andrew

+1

Bueno, para que lo sepas, si no hubieras utilizado el bit '{: action => ...}' - y hubieras hecho lo que sugerí arriba - hubieras tenido éxito. Lo que le estabas diciendo al generador de la url que generara era, de hecho, que querías publicar en una acción en tu controlador que se llamaba la salida de 'upload_photo_path (@photo)' - que ** en sí ** contiene el controlador y nombres de acción (como se puede ver en el error "No hay coincidencias de ruta ...") – davemyron

+0

Ok, hice una prueba de esto para estar seguro, y tienes razón, esto creó la ruta como dijiste. No voy a usarlo de la misma manera (otros problemas con mi implementación), pero esta es una solución válida. Gracias :) – Andrew

1

Su parámetro url debe ser

: url => {: action => "cargar"}


(respuesta original)

Apostaría que es porque su ruta espera una PUT y su forma está enviando un POST (probablemente porque @photo = Photo.new). Tiene varias opciones:

  1. cambiar la ruta para post 'upload'
  2. Cree su formulario con form_for @photo, :as => :post con el resto de sus argumentos
  3. Asegúrese @photo es un registro existente (por ejemplo, llamando create en lugar de new)

la opción más apropiada es, probablemente, uno de los primeros 2.

+0

Bueno, revisando estos: @photo es un registro existente seguro. El argumento: method está configurado como 'put' pero solo para asegurarme de que intenté cambiar la ruta para publicar 'upload' ... no hay dados. Usando: as =>: la publicación no lo corrigió, ni lo hizo: as =>: poner con la ruta establecida en 'poner actualización' – Andrew

+0

Intenta configurar la ruta para 'emparejar' la carga '. Además, publique la salida de 'rake routes'. –

+0

No lo corrigió ... – Andrew

2

Tuve el mismo problema y finalmente resolví una solución que no estoy seguro se llegó al caso anterior, ya que el póster original pasó a otro enfoque.

Mis rutas tenían

resources :members do 
    member do 
    get "invite" 
    post 'register' 
    end 
end 

Y "rutas rastrillo" incluyen

register_member POST /members/:id/register(.:format) {:protocol=>"http", :action=>"register", :controller=>"members"} 

Sin embargo, seguí recibiendo el error

Started POST "/members/149/register" for 127.0.0.1 at 2012-04-13 13:18:35 -0700 

ActionController::RoutingError (No route matches "/members/149/register"): 

Rendered /Users/lisa/.rvm/gems/[email protected]/gems/actionpack-3.0.9/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.1ms) 

y el problema se limitaba sólo a la forma generada por Rails de acuerdo con el siguiente form_for (nota, confirmé esto usando el cliente HTTP para POST manualmente a t él URL y vio que era encontrar la ruta)

<%= form_for @account, :url => register_member_path(@account.id) do |account_form| %> 
    ... 

he comprobado el método, he comprobado el camino, todo se veía bien. Lo que finalmente noté, recorriendo el formulario generado línea por línea:

<form accept-charset="UTF-8" action="/members/149/register" class="edit_member" id="edit_member_149" method="post"> 
    <div style="margin:0;padding:0;display:inline"> 
    <input name="utf8" type="hidden" value="&#x2713;" /> 
    <input name="_method" type="hidden" value="put" /> 
    <input name="authenticity_token" type="hidden" value="74pkMgRHfdowSfzjJGMILkAsivVNrJZ0iWYXRUgxyF0=" /> 
    </div> 
... 

Observe la entrada oculta name = "_ method". Me gustaría que el hecho de que Rails interpretara esto como PUT apareciera en los registros, eso hubiera hecho que mi depuración fuera mucho más rápida. Lo arreglé diciéndole al formulario explícitamente que use el método POST, que por supuesto ya estaba, pero diciéndole que eliminó la anulación de _método oculto. Supongo que hay alguna faceta acerca de @account que activó a Rails para usar el parámetro _method, pero @account debería ser un registro existente.

+0

Interesante, eso puede haberme afectado también, pero como utilicé 'match' en lugar de' post' en mis rutas, debería haber funcionado de cualquier manera en mi caso. No obstante, es una gran adición a esta pregunta, ya que estoy seguro de que a otros les resultará útil su solución. – Andrew

Cuestiones relacionadas