简体   繁体   中英

Rails routing issue, can't figure out the link path

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.

Actually I'm very surprised your code worked at all. A route must define two things

  • Some sort of regex against which the URL of the user is matched ( newsbites/frontindex is different than newsbites/backindex )
  • What do you want to do for a given URL ? You want to point to a controller action

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM