Вопрос

For some reason slide_path gives me /slides/1.1 for DELETE method rather than /albums/1/slides/1. Thanks in advance for any advice why it happens or/and how to solve it.

my spec fail:

 1) Slide Pages Delete slide
     Failure/Error: expect{page.find('.btn.btn-mini.btn-danger').click}.to change(Slide, :count).by(-1)
     ActionController::RoutingError:
       No route matches [DELETE] "/slides/1.1"
     # ./spec/features/slides_spec.rb:78:in `block (3 levels) in <top (required)>'
     # ./spec/features/slides_spec.rb:78:in `block (2 levels) in <top (required)>'

spec:

 scenario "Delete slide" do
    visit album_slides_url slide.album
    expect{page.find('.btn.btn-mini.btn-danger').click}.to change(Slide, :count).by(-1)
  end

view:

    <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
    slide_path(slide.album.id, slide.id),
    :method => :delete,
    :class => 'btn btn-mini btn-danger',
    :remote => true %>

rake routes:

  slide GET      /slides/:id(.:format)                                             slides#show
        PATCH    /slides/:id(.:format)                                             slides#update
        PUT      /slides/:id(.:format)                                             slides#update
        DELETE   /albums/:album_id/slides/:ids(.:format)                           slides#destroy # this is the one I expect to get
        PATCH    /albums/:album_id/slides/:ids/dest_album/:dest_album_id(.:format) slides#move
        PUT      /albums/:album_id/slides/:ids/dest_album/:dest_album_id(.:format) slides#move

routes.rb:

  resources :albums, except: :show do
    resources :slides, shallow: true, except: [:destroy, :patch, :put]    
    match 'slides/:ids', to: 'slides#destroy', via: :delete
    match 'slides/:ids/dest_album/:dest_album_id', to: 'slides#move', via: :patch
    match 'slides/:ids/dest_album/:dest_album_id', to: 'slides#move', via: :put
  end
Это было полезно?

Решение

As per your defined routes, the DELETE route is NOT a named route, so when you say slide_path(slide.album.id, slide.id) in your link, rails routes would automatically try to match it with the listed routes prefixed with slide and with DELETE request.

To route the Delete Slide link properly to the DELETE route, you would need to update the routes as below:

resources :albums, except: :show do
  resources :slides, shallow: true, except: [:destroy, :patch, :put]    
  match 'slides/:ids', to: 'slides#destroy', via: :delete, as: :slide ## Note as option
  match 'slides/:ids/dest_album/:dest_album_id', to: 'slides#move', via: :patch
  match 'slides/:ids/dest_album/:dest_album_id', to: 'slides#move', via: :put
end

This will create the DELETE named route as below:

album_slide DELETE /albums/:album_id/slides/:ids(.:format)  slides#destroy

Now, update the Delete Slide link to map to this route:

<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
    album_slide_path(slide.album.id, slide.id),
    :method => :delete,
    :class => 'btn btn-mini btn-danger',
    :remote => true %>

UPDATE

Your route was NOT a named route. As per your currently defined routes slide_path is only available for the following routes:

  slide GET      /slides/:id(.:format)                                             slides#show
        PATCH    /slides/:id(.:format)                                             slides#update
        PUT      /slides/:id(.:format)       

which were created with resources :slides, shallow: true, except: [:destroy, :patch, :put]

So, when you called slide_path(slide.album.id, slide.id) with two arguments, rails router tried to convert it into a path

/slides/:id(.:format) 

so you received a request with path

slides/1.1 
       ^ ^
       a b

where

a => refers to :id dynamic segment of the slide_path route and value of slide.album.id was set to it

b => refers to (.:format) part of the slide_path route and value of slide.id was set to it. Format refers to the extension (.html, .json, etc) so you received .1 in the path as slide.id was treated as format

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top