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)
だけを実行した場合はどうなりますか?
ただし、メンバーにアップロードするのは少し奇妙に思えます。これは単なる作成方法ですか(この場合、コレクションパスにPOST)する必要があります)?
私は同じ問題を抱えていましたが、元のポスターが別のアプローチに移行したため、最終的に上記のケースで到達したかどうかわからない解決策に取り組みました。
私のルートは
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)
問題は、以下のform_forに従ってRailsによって生成されたフォームのみに限定されていました(HTTPクライアントを使用して手動でこれを確認したことに注意してくださいPOST URLとルートを見つけていたのを見た)
<%= form_for @account, :url => register_member_path(@account.id) do |account_form| %>
...
メソッドをチェックし、パスをチェックしました。すべてが良さそうです。生成されたフォームを1行ずつ精査して、最終的に気付いたのは次のとおりです。
<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>
...
非表示の入力name = "_method"に注意してください。 RailsがこれをPUTがログに表示されたものとして解釈していたため、デバッグが大幅に高速化されたと思います。フォームに=を使用するように明示的に指示することで修正しました。 POSTメソッド、もちろんそれはすでにありましたが、隠された_methodオーバーライドを削除したことを伝えています。使用するRailsをトリガーした@accountに関するいくつかの側面があると思います_methodパラメーターですが、@ accountは既存のレコードである必要があります。
url
パラメータは次のようになります
:url => {:action => "upload"}
(元の返信)
ルートがPUT
を予期していて、フォームがPOST
を送信しているためだと思います(おそらく@photo = Photo.new
のため)。いくつかのオプションがあります。
post 'upload'
に変更しますform_for @photo, :as => :post
と残りの引数を使用してフォームを作成します@photo
が既存のレコードであることを確認します(たとえば、create
の代わりにnew
を呼び出します)最も適切な選択は、おそらく最初の2つのうちの1つです。