Reputation: 18208
I'm trying to add a path to my application. I have code that functions as I'd like, but I'd like to group it differently so that it's more intuitive to read. Here's the code:
get 'posts/search' => 'posts#search',
:as => :search_posts
put 'posts/search_result' => 'posts#search_result',
:as => :search_posts_result
resources :posts do
end
but I'd like to do something like this:
resources :posts do
get 'posts/search' => 'posts#search',
:as => :search_posts
put 'posts/search_result' => 'posts#search_result',
:as => :search_posts_result
end
It's a really small difference, but doing it the latter way defines runs resources :posts
first. As a result, Rails tries to match /posts/search
to /posts/:id
(for show) and gives an error as it can't find a post with id 'search'. Is there a way I can tell rails to run the get and put definitions before running resources :posts
?
Upvotes: 0
Views: 123
Reputation: 80051
The reason your routes aren't working is because they are defined on each member of posts, so /posts/1/posts/search
. You should run rake routes
to check where your routes are going.
To fix your problem, you would probably want to fix those route paths and make sure you're defining the search route on the entire collection. If this is confusing, check the guide.
resources :posts do
get :search, :on => :collection
end
You don't need all that other stuff you had, either. This will create all of the following routes for you:
search_posts GET /posts/search(.:format) {:action=>"search", :controller=>"posts"}
posts GET /posts(.:format) {:action=>"index", :controller=>"posts"}
POST /posts(.:format) {:action=>"create", :controller=>"posts"}
new_post GET /posts/new(.:format) {:action=>"new", :controller=>"posts"}
edit_post GET /posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
post GET /posts/:id(.:format) {:action=>"show", :controller=>"posts"}
PUT /posts/:id(.:format) {:action=>"update", :controller=>"posts"}
DELETE /posts/:id(.:format) {:action=>"destroy", :controller=>"posts"}
Rails defines the routes on the entire collection before the default resourceful routes (as you can see above) so that your routes take precedence.
And as far as your PUT posts#search_result
method, well, that's really confusing — you want to update a search result manually?
Per the comments: I'd recommend something like this instead of having a separate action for search results. Typically a search page looks the same with or without results, except the error message if you do a search and nothing turns up. Gracefully handling the case that a search page is shown without a query being present lets you nix a redundant action.
def search
@query == params[:q] || ''
# search logic
flash[:error] = 'Nothing found message' if @results.empty? unless @query.blank?
end
Upvotes: 1
Reputation: 2476
resources :posts do
collection do
get :search, :as => :search_posts
put :search_result, :as => :search_posts_result
end
end
Upvotes: 1