Adam White
Adam White

Reputation: 1136

Incorrectly routing /index to /show in Rails

There must be an obvious answer to this, but I'm at a loss.

I have a Rails app which tracks sites. For whatever reason, localhost:3000/sites leads to my index page. However, localhost:3000/sites/index leads to my show page.

Why is this?

Below is the routes file:

Rails.application.routes.draw do

  resources :sites

Below is the sites controller:

class SitesController < ApplicationController

  def index
  end

  def show
  end

end

In views/sites, there is the index.html.erb and show.html.erb files. The former displays at /sites, the latter displays at /sites/index (and /sites/show as one would expect).

Thanks for any help!

UPDATE:

When I rake routes, I get:

Prefix Verb   URI Pattern               Controller#Action
sites GET    /sites(.:format)          sites#index
      POST   /sites(.:format)          sites#create
new_site GET    /sites/new(.:format)      sites#new
edit_site GET    /sites/:id/edit(.:format) sites#edit
 site GET    /sites/:id(.:format)      sites#show
      PATCH  /sites/:id(.:format)      sites#update
      PUT    /sites/:id(.:format)      sites#update
      DELETE /sites/:id(.:format)      sites#destroy

These routes are what one would expect, but I guess I'm just surprised that sites/index presumes index is an :id and therefore routes the request to show.

I suppose I had never explicitly encountered that behavior before.

Upvotes: 1

Views: 585

Answers (3)

Mark Swardstrom
Mark Swardstrom

Reputation: 18080

There are 7 basic actions in a controller by default, only 2 of them are matched by name in the url - (new and edit). These 2 are HTML constructs, they are just a way of rendering a form.

The other 5 (index, show, update, create, destroy) are the more basic routes and do the work to display and modify resources. They are referenced by only two url patterns (the two patterns you mentioned above - eg '/sites' and '/sites/:id'). They are differentiated by the method that goes along with the request: (Patch, Post, Get, Delete). So, "/sites" would be used for create and index. "/sites/:id" would be used for show, destroy, and update.

The action in the controller is not referenced by the url exactly - the url pattern and the request method together are used to call the associated controller method.

In the request "/sites/index", as the string "index" is in the url, the only route that matches is one that has a variable after "/sites/". :id is just a variable, not necessarily an integer. Since the request was a GET, the first (and only) route match is sites#show. "index" will be the value of params[:id] passed into the show action.

Upvotes: 4

Greg Answer
Greg Answer

Reputation: 717

This is the way routing works in Rails. Take a look at Rails routing to get a better understanding of how this works. Especially the Rails resource routing section.

Generally when you setup a resource route as you did the urls would be as follows:

example.com/sites #=> index page
example.com/sites/:id #=> show page. A specific site, where :id would be the unique identifier

# Here's an example URL with a specific site
example.com/sites/stackoverflow

Upvotes: 3

Ivan
Ivan

Reputation: 235

Your index page is at: localhost:3000/sites

Navigate to localhost:3000/rails/info/routes to see your full app routes in development mode.

Upvotes: 2

Related Questions