Ruby on rails 用于自定义操作的Rails 3表单

Ruby on rails 用于自定义操作的Rails 3表单,ruby-on-rails,forms,ruby-on-rails-3,custom-action,Ruby On Rails,Forms,Ruby On Rails 3,Custom Action,在Rails 3中,我无法将表单路由到自定义操作。以下是我的路线: resources :photos do resources :comments collection do get 'update_states' end member do put 'upload' end end 以下是表格_: form_for @photo, :remote => true, :url => { :action =&g

在Rails 3中,我无法将表单路由到自定义操作。以下是我的路线:

resources :photos do
    resources :comments
    collection do
        get 'update_states'
    end
    member do
        put 'upload'
    end
end
以下是表格_:

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"}
以下是我将路由更改为匹配“上载”时的相关路由:

 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 |

我仍然得到:


没有路由匹配{:action=>“upload”,:controller=>“photos”}
您的
url
参数应该是

:url=>{:操作=>“上载”}


(原始答复)

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

  • 将您的路线更改为“上传”
  • 用@photo的
    form_创建表单,:as=>:post
    和其他参数
  • 确保
    @photo
    是现有记录(例如,通过调用
    create
    而不是
    new

  • 最合适的选择可能是前两个选项中的一个。

    如果您只是
    :url=>上传照片路径(@photo)


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

    我也遇到了同样的问题,最终找到了一个解决方案,但我不确定在上述情况下是否达到了该解决方案,因为原始海报采用了另一种方法

    我的路线有

    resources :members  do
      member do
        get "invite" 
        post 'register'
      end
    end
    
    包括"耙路"

    但我还是不断地犯错误

    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根据以下表单生成的表单(注意,我使用HTTP客户端手动发布到URL并看到它正在查找路由)

    register_member_path(@account.id)do | account_form |%>
    ... 
    
    我检查了方法,检查了路径,一切都很好。我最后注意到的是,逐行搜索生成的表单:

    <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>
    ...
    
    
    ...
    

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

    好吧,通过这些检查:@photo确实是一个现有记录。:method参数设置为“put”,但只是为了确保我尝试将路由更改为post“upload”。。。没有骰子。使用:as=>:post没有修复它,也没有:as=>:将路由设置为“put update”的put尝试将路由设置为
    匹配“upload”
    。另外,发布
    rake routes
    的输出。问题在于
    url
    参数(请参阅更新的答案)。很抱歉没有立即捕捉到这一点…这也是我最初的想法,但无论我以何种方式放置action为我提供的路由,
    无路由匹配{:action=>“upload”,:controller=>“photos”}
    如果您像我的回复一样传递
    url
    ,并将
    路由.rb
    更改为让
    匹配
    ,而不是
    放置
    ,您仍然会收到相同的错误消息?我可能稍后会尝试,但我决定朝一个全新的方向走。上传到成员的原因是,当用户单击“新建”时,我正在创建、准备和保存,然后他们在第一次填写信息时实际上正在编辑记录。我这样做是因为我希望能够在运行时保存进度,并且有几个关联的模型需要父id才能正确保存。。。。不管怎么说,这太痛苦了,所以我正试图想出一个全新的方法。正如你所知,如果你没有使用
    {:action=>…}
    位,而不是按照我上面的建议,你就会成功。事实上,您告诉url生成帮助程序生成的内容是,您想在控制器上发布一个名为“
    上传照片”路径(@photo)
    ”输出的操作,该路径本身包含控制器和操作名称(正如您在“No route matches…”错误中看到的)好的,我做了一个测试以确保,你是对的,这确实创造了你所说的路径。我不再以同样的方式使用它(实现中的其他问题),但这是一个有效的解决方案。谢谢:)很有趣,这可能也影响了我,但因为我在我的路线中使用了
    match
    而不是
    post
    ,所以在我的情况下,这两种方法都应该有效。不过,这是一个很好的补充,因为我相信其他人会发现您的解决方案很有用!
    <%= form_for @account, :url => register_member_path(@account.id) do |account_form| %>
       ... 
    
    <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>
    ...