James N
James N

Reputation: 533

rails 5 - show route not working or generating

I am digging into rails 5.2.0. I am working on a dead simple app to get my feet wet on anything new (mainly work in production w/ rails 3 & 4 apps).

I am on my index path, rendering something like

<ul>
    <% @questions.each do |question| %>
        <li><%= link_to question.title, questions_path(question.id) %></li>
    <% end %>
</ul>

My controller looks like

def index
    @questions = Question.all
end

def new
    @question = Question.new
end

def create
    @question = Question.new(title: params['question']['title'], body: params['question']['body'])

    if @question.save 
        redirect_to '/'
    else
        redirect_to '/questions/new'
    end
end

def show
    @question = Question.find(params[:id])
end

and my routes look like

get '/' => 'questions#index'

get '/questions/new' => 'questions#new'

post '/questions' => 'questions#create'

get '/questions/:id' => 'questions#show'

This is all fine, but when i go to click on the links in my index, i get a path that's http://localhost:3000/questions.8, and when i run rails routes, I get

Prefix Verb URI Pattern                                                                              Controller#Action
                          GET  /                                                                                        questions#index
                          GET  /questions/:id(.:format)                                                                 questions#show
            questions_new GET  /questions/new(.:format)                                                                 questions#new
                questions POST /questions(.:format)                                                                     questions#create

and if you notice it did not generate a path for the show route. The only thing that works is doing something like this in the index

<% @questions.each do |question| %>
    <li><%= link_to question.title, "/questions/#{question.id}" %></li>
<% end %>

which is fine but defeats the whole purpose of these routes.

Does anyone see what I'm doing wrong or forgetting? Is this a rails 5 thing, or just something dumb in my code?

Upvotes: 0

Views: 942

Answers (2)

sa77
sa77

Reputation: 3603

You should define your show route as

get '/questions/:id' => 'questions#show', :as => :question 

then use it as question_path(question) (notice no plural) because questions_path is already taken by the route to questions#index.

But you're better off using rails' routes helper method resources if you want cleaner solution.

resources :questions, :only => [:index, :new, :create, :show] 

Upvotes: 0

jvillian
jvillian

Reputation: 20263

Your problem is that questions_path routes to /questions, so when you do,

link_to question.title, questions_path(question.id)

You're getting /questions with the question.id appended as .8 (because questions_path doesn't expect an argument).

Instead, shouldn't you just do:

root 'questions#index'
resources :questions

Which would give you:

          root GET    /                                 questions#index
     questions GET    /questions(.:format)              questions#index
               POST   /questions(.:format)              questions#create
  new_question GET    /questions/new(.:format)          questions#new
 edit_question GET    /questions/:id/edit(.:format)     questions#edit
      question GET    /questions/:id(.:format)          questions#show
               PATCH  /questions/:id(.:format)          questions#update
               PUT    /questions/:id(.:format)          questions#update
               DELETE /questions/:id(.:format)          questions#destroy    

(You can prune the routes using :only or :except, if you like.)

And then you can do:

<ul>
  <% @questions.each do |question| %>
    <li><%= link_to question.title, question %></li>
  <% end %>
</ul> 

Rails should infer the correct route from the question variable and create a link to /questions/8 as described in the docs.

Upvotes: 1

Related Questions