2011-01-15 29 views
15

Tôi đang gặp rắc rối định tuyến là một hình thức để một hành động tùy chỉnh trong Rails 3. Dưới đây là tuyến đường của tôi:Rails 3 thức biểu diễn cho Tuỳ chỉnh hành động

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

Đây là form_for:

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

Và đây là thông báo lỗi:

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

... điều này đặc biệt bực bội vì "ảnh /: id/tải lên" là chính xác hành động chính xác cho biểu mẫu này.

Tôi đang thiếu gì?

CHỈNH SỬA - Dưới đây là những hình ảnh liên quan đến gốc các tuyến đường:

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"} 

Dưới đây là các tuyến đường có liên quan khi tôi đã thay đổi con đường để 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"} 

Thật không may 'trận đấu' không làm việc tốt hơn ...

- EDIT -

Chỉ cần để xác nhận kịch bản khác đây ... với điều này trong các tuyến đường:

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

và điều này trong giao diện:

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

tôi vẫn nhận được:

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

Trả lời

27

Nếu bạn chỉ cần :url => upload_photo_path(@photo) thì sao?

Có vẻ như bạn hơi lạ khi tải lên thành viên. Đây có phải chỉ là một phương pháp sáng tạo (trong trường hợp đó bạn chỉ nên POST vào đường dẫn thu thập)?

+0

Tôi có thể thử điều đó sau, nhưng tôi đã quyết định đi theo một hướng hoàn toàn mới. Lý do tải lên thành viên là tôi đã tạo, chuẩn bị và tiết kiệm khi người dùng nhấp vào 'mới', sau đó họ thực sự chỉnh sửa bản ghi khi họ điền thông tin lần đầu tiên. Tôi đã làm điều này bởi vì tôi muốn để có thể lưu tiến bộ của họ khi họ đi, và có một số mô hình liên quan cần id mẹ để tiết kiệm đúng .... anyway, điều này là quá nhiều đau, vì vậy tôi đang cố gắng để đưa ra một cách tiếp cận hoàn toàn mới. – Andrew

+1

Cũng chỉ để bạn biết, nếu chỉ có bạn đã không sử dụng '{: action => ...}' bit - và thay vào đó đã làm những gì tôi đề nghị ở trên - bạn sẽ thành công. Những gì bạn đã nói với trình tạo trợ giúp tạo url là, trên thực tế, bạn muốn đăng lên một hành động trên bộ điều khiển của bạn, được đặt tên là đầu ra của 'upload_photo_path (@photo)' - mà ** chính nó ** chứa bộ điều khiển và tên hành động (như bạn có thể thấy trong lỗi "No route matches ...") – davemyron

+0

Ok, tôi đã kiểm tra điều này để chắc chắn, và bạn nói đúng, điều này đã tạo ra con đường như bạn đã nói. Tôi sẽ không sử dụng nó theo cách này nữa (các vấn đề khác với việc thực hiện của tôi), nhưng đây là một giải pháp hợp lệ. Cảm ơn :) – Andrew

1

Thông số url của bạn phải là

: url => {: action => "tải lên"}


(Original trả lời)

tôi sẽ đặt cược đó là vì tuyến đường của bạn hy vọng một PUT và hình thức của bạn đang gửi một POST (có lẽ vì @photo = Photo.new). Bạn có một vài lựa chọn:

  1. Thay đổi tuyến đường của bạn để post 'upload'
  2. Tạo mẫu của bạn với form_for @photo, :as => :post với phần còn lại của các đối số của bạn
  3. Hãy chắc chắn rằng @photo là một kỷ lục hiện tại (ví dụ như bằng cách gọi create thay vì new)

Lựa chọn phù hợp nhất có lẽ là một trong những đầu tiên 2.

+0

Vâng, hãy kiểm tra thông qua những điều sau: @photo là bản ghi hiện có chắc chắn. Đối số: phương thức được đặt thành 'đặt' nhưng chỉ để chắc chắn tôi đã thử thay đổi tuyến đường thành đăng 'tải lên' ... không có súc sắc. Sử dụng: as =>: bài đăng không khắc phục được, cũng không làm: as =>: đặt với tuyến đường được đặt thành 'đặt bản cập nhật' – Andrew

+0

Thử đặt tuyến đường thành 'tải lên 'khớp'. Ngoài ra, đăng đầu ra của 'rake routes'. –

+0

Không khắc phục được sự cố ... – Andrew

2

Tôi đã có cùng một vấn đề và cuối cùng làm việc thông qua một giải pháp mà tôi không chắc chắn đã đạt được trong trường hợp trên, kể từ khi áp phích ban đầu chuyển sang cách tiếp cận khác.

đường tôi đã

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

Và "đường cào" bao gồm

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

Tuy nhiên, tôi vẫn tiếp tục nhận được lỗi

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) 

và vấn đề đã được giới hạn chỉ với hình thức tạo bởi Rails theo form_for bên dưới (lưu ý tôi đã xác nhận điều này bằng cách sử dụng HTTP client để POST bằng tay URL của anh ấy và thấy nó đang tìm lộ trình)

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

Tôi đã kiểm tra phương pháp, tôi đã kiểm tra đường dẫn, mọi thứ đều tốt. Những gì tôi cuối cùng đã nhận thấy, cọ rửa dòng biểu mẫu được tạo theo dòng:

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

Chú ý tên đầu vào bị ẩn = "_ method". Tôi ước rằng Rails đã giải thích điều này như là một PUT đã được hiển thị trong nhật ký, điều đó sẽ làm cho việc gỡ lỗi của tôi nhanh hơn rất nhiều. Tôi cố định nó bằng cách nói cho biểu mẫu một cách rõ ràng để sử dụng phương thức POST, mà tất nhiên nó đã được, nhưng nói với nó rằng loại bỏ các ghi đè ẩn _method. Tôi giả sử có một số khía cạnh về @account đã kích hoạt Rails để sử dụng tham số _method, nhưng @account phải là một bản ghi hiện có.

+0

Thú vị, điều đó có thể đã ảnh hưởng đến tôi, nhưng vì tôi đã sử dụng 'match' thay vì' post' trong các tuyến đường của tôi nên nó đã hoạt động theo cách của tôi. Tuy nhiên, thêm vào câu hỏi này, vì tôi chắc rằng những người khác sẽ tìm thấy giải pháp của bạn hữu ích! – Andrew

Các vấn đề liên quan