Reputation:
I have a database full of text_message records. I am trying to create a custom "list all text messages" page.
Here is my relevant part of my routes.rb file:
resources :text_messages
get '/text_messages/all_messages', to: 'text_messages#all_messages'
I have the standard RESTful controller methods, then my own all_messages method:
def all_messages
@text_messages = TextMessage.order('send_time desc')
end
However, whenever I visit "localhost:port/text_messages/all_messages", I get an error:
ActiveRecord::RecordNotFound in TextMessagesController#show
Couldn't find TextMessage with 'id'=all_messages
So, Rails is getting something after 'text_messages/' and automatically assuming it is an id, even thought it is a string, and is completely ignoring my route. How do I get it to use me route and not try to use show()?
I am using Rails 4.2.
Upvotes: 1
Views: 1349
Reputation: 1484
It is just because you have defined
resources :text_messages
before
get '/text_messages/all_messages', to: 'text_messages#all_messages'
by default resources add one route
get '/text_messages/:id'
which goes to the show action. this id can be any word or anything. currently when you are trying to call your all_messages
it consider all_messages
as id and goes to your show action and generate the error.
You can resolve this in 2 ways :
Move your custom route above the resources something like below:
get '/text_messages/all_messages', to: 'text_messages#all_messages'
resources :text_messages
Use collection with resource as
resources :text_messages do
get 'all_messages', on: :collection
end
or
resources :text_messages do
collection do
get 'all_messages'
end
end
Upvotes: 3
Reputation: 5609
You need to use the collection
method:
This will enable Rails to recognize paths such as
/text_messages/all_messages
with GET, and route to the all_messages action ofTextMessagesController
. (source)
Change your routes like that:
resources :text_messages do
get 'all_messages', on: :collection
end
Without collection, any route like 'text_messages/<a parameter>'
hits the "show" action.
Upvotes: 1