Rails 3表单用于自定义操作

我在将表单路由到Rails 3中的自定义操作时遇到问题。以下是我的路由:

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

这是form_for:

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

这是错误信息:

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

…这尤其令人沮丧,因为“photos /:id / 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 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"} 

以下是我更改路线以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"} 

不幸的是’匹配’没有更好的工作……

– 编辑 –

只是为了确认另一种情况……在路线中:

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

这在视图中:

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

我还是得到:

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

如果您这样做:url => upload_photo_path(@photo)

你上传给会员似乎有点奇怪。 这只是一种创建方法(在这种情况下你应该只发布到收集路径)?

我遇到了同样的问题,并最终找到了一个我不确定在上述情况下达成的解决方案,因为原始海报转向了另一种方法。

我的路线了

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

并包括“耙路”

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

但我一直在收到错误

 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) 

并且问题仅限于Rails根据以下form_for生成的表单(注意我使用HTTP客户端确认了这一点,手动POST到URL并看到它正在查找路由)

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

我检查了方法,检查了路径,一切都很好看。 我最终注意到的是,逐行搜索生成的表单:

 
...

注意隐藏的输入名称=“_方法”。 我希望Rails将这个解释为PUT已经出现在日志中,这将使我的调试速度更快。 我通过明确告诉表单使用POST方法来修复它,当然它已经是,但告诉它删除了隐藏的_method覆盖。 我假设@account有一些方面触发Rails使用_method参数,但@account应该是现有记录。

你的url参数应该是

:url => {:action =>“upload”}


(原始回复)

我敢打赌,因为你的路线需要一个PUT而你的表格正在发送一个POST (可能是因为@photo = Photo.new )。 你有几个选择:

  1. 更改您的路线以post 'upload'
  2. 使用form_for @photo, :as => :post创建表单form_for @photo, :as => :post使用其余参数发布
  3. 确保@photo是现有记录(例如,通过调用create而不是new

最合适的选择可能是前两个选择之一。