Reputation: 533
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
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
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