ruby-on-rails - form_tag - form_with ruby on rails
Rails 3 Formulario para acción personalizada (3)
¿Qué pasa si lo acaba de hacer :url => upload_photo_path(@photo)
?
Sin embargo, parece un poco extraño que estés 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)?
Tengo problemas para enrutar un formulario a una acción personalizada en Rails 3. Estas son mis rutas:
resources :photos do
resources :comments
collection do
get ''update_states''
end
member do
put ''upload''
end
end
Aquí está el form_for:
form_for @photo, :remote => true, :url => { :action => upload_photo_path(@photo) }, :html => { :multipart => :true, :method => ''put'' } do |f|
Y aquí está el mensaje de error:
No route matches {:action=>"/photos/42/upload", :controller=>"photos"}
... esto es especialmente frustrante porque "photos /: id / upload" es exactamente la acción correcta para este formulario.
¿Qué me estoy perdiendo?
EDICIONES - Aquí están las rutas originales relacionadas con fotos:
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"}
Aquí están las rutas relevantes cuando cambié la ruta para que 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"}
Desafortunadamente, el "emparejamiento" no funcionó mejor ...
- EDITAR -
Solo 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 en la vista:
form_for @photo, :remote => true, :url => { :action => ''upload'' }, :html => { :multipart => :true, :id => ''photo_upload'' } do |f|
Aún consigo:
No route matches {:action=>"upload", :controller=>"photos"}
Tu parámetro url
debe ser
: url => {: acción => "subir"}
(Respuesta original)
Apuesto a que es porque su ruta espera un PUT
y su formulario está enviando un POST
(probablemente porque @photo = Photo.new
). Tienes varias opciones:
- Cambia tu ruta para
post ''upload''
- Crea tu formulario con
form_for @photo, :as => :post
con el resto de tus argumentos - Asegúrese de que
@photo
sea un registro existente (por ejemplo, llamando acreate
lugar denew
)
La elección más apropiada es probablemente una de las primeras 2.
Tuve el mismo problema y finalmente resolví una solución que no estaba segura de haber sido alcanzada en el 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 de rake" incluidas
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/ruby-1.9.2-p180@stv/gems/actionpack-3.0.9/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.1ms)
y el problema se limitó solo a la forma generada por Rails de acuerdo con el siguiente form_for (nota: confirmé esto usando el cliente HTTP para POSTAR manualmente a la URL y vi que estaba buscando la ruta)
<%= form_for @account, :url => register_member_path(@account.id) do |account_form| %>
...
Revisé el método, revisé el camino, todo se veía bien. Lo que finalmente noté, recorriendo la forma generada 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="✓" />
<input name="_method" type="hidden" value="put" />
<input name="authenticity_token" type="hidden" value="74pkMgRHfdowSfzjJGMILkAsivVNrJZ0iWYXRUgxyF0=" />
</div>
...
Observe el nombre de la entrada oculta = "_ método". Me gustaría que el hecho de que Rails interpretara esto como PUT apareciera en los registros, eso habría 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.