Rails ignores collection route and goes with show

2020-08-09 08:02发布

I have the following routes set up in my routes.rb file:

resources :people do 
  collection do
    get :search
  end
end

When i do a get action on the url: http://localhost:3000/people/search.json?term=stepeb, the server reports that it's responding with the show action, with the correct term parameter, but also has an id parameter, set to "search".

The problem, as i see it, are the two urls the show url would be:

/people/:id

and i believe that the router is matching that route before it gets to /people/search

If that is the case, how would collection based routes ever work? Wouldnt they all get caught by the show action?

The relevant part of rake routes is as follows:

 search_people GET      /people/search(.:format)                                                         {:action=>"search", :controller=>"people"}
                                     GET      /people(.:format)                                                                {:action=>"index", :controller=>"people"}
                              people POST     /people(.:format)                                                                {:action=>"create", :controller=>"people"}
                          new_person GET      /people/new(.:format)                                                            {:action=>"new", :controller=>"people"}
                                     GET      /people/:id(.:format)                                                            {:action=>"show", :controller=>"people"}
                                     PUT      /people/:id(.:format)                                                            {:action=>"update", :controller=>"people"}
                              person DELETE   /people/:id(.:format)                                                            {:action=>"destroy", :controller=>"people"}
                         edit_person GET      /people/:id/edit(.:format)                                                       {:action=>"edit", :controller=>"people"}

3条回答
手持菜刀,她持情操
2楼-- · 2020-08-09 08:42

I also had a similar problem. According to your example my routes.rb looked like this

resources :people

...

resources :people do
    collection do
      get :search
    end
  end

Changed it to:

resources :people do
    collection do
      get :search
    end
  end

...

resources :people

and i can access the collection... btw, is this the appropriate way of adding routes? i.e. is it good style to just add a new route when adding an action to a controller and leaving the "old" resources :people like it is?

查看更多
Anthone
3楼-- · 2020-08-09 08:46

Doh, forget this one. Turns out i had a duplicate resources :people line at the top of the routes file. Rails was hitting that first. Seems to me there really should be a check for duplicate route definition in there.

查看更多
霸刀☆藐视天下
4楼-- · 2020-08-09 09:07

What version of Rails are you running? Try creating a test application with just the code you have provided here and see if it works. There is probably something else causing a conflict that you have not mentioned.

Using your code on Rails 3.0.0beta4 produced the desired results:

Started GET "/people/search.json?term=boo" for 192.168.1.2 at 2010-06-23 03:39:26 -0400
  Processing by PeopleController#search as JSON
  Parameters: {"term"=>"boo"}
Completed   in 49ms

Here is my routes file:

  resources :people do
    collection do
      get :search
    end
  end

I have a people_controller.rb with a search method defined.

查看更多
登录 后发表回答