Reputation: 293
Let me fair from the outset, and tell you that I've 'solved' the problem I'm describing. But a solution that you don't understand is not really a solution, now is it?
I have a resource, Newsbites. I have an index page for Newsbites. All my CRUD actions work fine.
I created a separate index (frontindex.html.erb
) that acts as the front page of my website to show the newest Newsbites. The formatting is different from my normal index so readers get a larger photo, more of the text of the article(more ads too:).
In my routing table, I have the following statements:
resources :newsbites
get 'newsbites/frontindex'
root 'newsbites#frontindex'
Rake routes show the following:
newsbites_frontindex GET /newsbites/frontindex(.:format) newsbites#frontindex
If I load my website from the root (localhost:3000), it works great. There is a separate menu page that is rendered at the top, and it loads fine. I can click on all links, except the 'Home
' link, and they work fine.
The 'Home' link is:
<%= link_to 'Home', newsbites_frontindex_path %>
When I click on the linked, I get the following error:
Couldn't find Newsbite with 'id'=frontindex
The error points to the 'show
' action of my Newbites controller. Here are the frontindex
and show def from the controller. They appear exactly as I'm posting them:
def frontindex
@newsbites = Newsbite.all
end
def show
@newsbite = Newsbite.find(params[:id])
end
I don't get it. Why is the show action being called by newbites_frontindex_path
when there is both a def and views that match? Now, I can get around this by simply pointing home to root_path
. But that doesn't help me understand. What if this was not the root of the site?
Any help would be greatly appreciated.
Upvotes: 1
Views: 1184
Reputation: 13979
Actually I'm very surprised your code worked at all. A route must define two things
newsbites/frontindex
is different than newsbites/backindex
)Rails won't usually "guess" what that action is. Or maybe, he was still able to "guess" that you wanted to use the newsbites
controller, but it didn't guess the action right this time :(.
You should declare the root like this, which is what you did
root 'controller#action'
For the rest, there are two ways you can declare it. I prefer the second one
resources :newsbites
get 'newsbites/frontindex', to: 'newsbites#frontindex'
resources :newsbites do
# stuff added here will have the context of the `newsbites` controller already
get 'frontindex', on: :collection # the name of the action is inferred to be `frontindex`
end
The on: :collection
, means that 'frontindex' is an action that concerns ALL the newsbites, so the URL generated will be newsbites/frontindex
.
On the other hand get 'custom_action', on: :member
, means that the custom_action targets a specific item, the URL generated would look like newsbites/:id/custom_action
EDIT : Rails also generate path_helpers based on the route declaration
get 'test', to: 'newsbites#frontindex'
get 'test/something', to: 'newsbites#frontindex'
resources :newsbites do
get 'frontindex', on: :collection
get 'custom_action', on: :member
Will generate path helpers
test_path
test_something_path
# CRUD helpers : new/edit/show/delete, etc. helpers
frontindex_newsbites_path
custom_actions_newsbite_path(ID) # without s !
You can always override this by adding an as:
option
get 'custom_action', on: :member, as: 'something_cool'
# => something_cool_newsbites_path
Upvotes: 1
Reputation: 11162
Rails routes thinks that frontindex
is an id. That's what the error message says. So it goes to GET newsbite/:id
which maps to show
.
You need to find a way let Rails routes know that frontindex
is not an id
.
On a side note: The order in which you define routes matters. The first one matched will be used. If you have GET newsbite/:id
and GET newsbite/frontindex
then the one that appears first will be matched. In your case this is the first one.
Maybe try to change the order.
Upvotes: 0