I have the following in my routes file
resources :users do
resource :question
end
which creates a /users/:user_id/question route to question#show among other ones. However instead of a URL which has user id in it to show every question the particular user created, I want a URL to show details of one specific question. Something like /question/:id
So to do this I added the line below to my routes file
resources :questions, param: :question_id
which generated a list of routes
questions_path GET /questions(.:format) questions#index
POST /questions(.:format) questions#create
new_question_path GET /questions/new(.:format) questions#new
edit_question_path GET /questions/:id/edit(.:format) questions#edit
question_path GET /questions/:id(.:format) questions#show
PATCH /questions/:id(.:format) questions#update
PUT /questions/:id(.:format) questions#update
DELETE /questions/:id(.:format)
This list produces the /questions/:id path but unfortunately with the same questions#show connection which collides with the previous one. So I removed the "resources :questions, param: :question" and added the following
get 'questions/:id', :to => 'questions#show_question'
This produces the appropriate route but for some reason doesn't get rid of routes created from "resources :questions, param: :question" even after restarting the server. So every time i visit /question/:id it's going to question#show instead of question#show_question
How do i get rid of the effect of "resources :questions, param: :question" even after having removed it from the routes.rb file?
I would remove the route get 'questions/:id', :to => 'questions#show_question'
and use shallow routes instead
resources :users do
resources :questions, shallow: true
end
And then your url_helper should be
<td><%= link_to 'Show', question_path(question) %></td>
This allows URLs for resources that otherwise would be deeply nested such as a comment on a blog post like /users/a-long-permalink/comments/1234 to be shortened to just /comments/1234.
More info on shallow routes here http://edgeguides.rubyonrails.org/routing.html
Related
(Rails 4.2)
I have a miss-match of routes that's in the routes.rb file vs the generated from my page. What is it I am doing wrong?
This is the raked route I want to access :
see_hint_deck_card_tracker GET /decks/:deck_id/cards/:card_id/trackers/:id/see_hint(.:format) trackers#see_hint
I am actually taken to what I think is the correct url, but it tells me I don't have a route for this page:
http://localhost:3000/decks/9/cards/2/trackers/1/see_hint
I have the following routes:
resources :decks do
resources :cards do
resources :trackers do
member do
get 'see_hint'
end
end
end
end
app/controllers/tracker_controller.rb :
class TrackerController < ApplicationController
def show_hint
puts 'we found this'
end
end
inside my /decks/:id/cards/:id/show I have this link_to: (get_tracker, calls for a helper method to get the correct tracker)
<%= link_to "Reveal Hint", see_hint_deck_card_tracker_path(#card.deck, #card, get_tracker), id: "reveal_hint_button" %>
I think your error message is probably telling you you don't have a Controller for that route, not that the Route is missing. This is because you're using the plural resources in your routes.rb, but your controller name is singular:
# Your Code:
resources :trackers
controller TrackerController
# Expected Code:
resources :trackers
controller TrackersController
^^^
You'll also want to make sure your controller is available at app/controllers/trackers_controller.rb (note the plurality).
think of the resource routing of a photo-class for example.
If I this to my routes.rb I will get following routes:
resources :photos
# GET '/photos/', :to => 'photos#index'
# GET '/photos/:photo_id/, :to => 'photos#show'
# and so on and so on
Now what I want is to replace the word /photos in all the routes with a simple /p so that I can get a short URL like /p/1 for the first photo. Is there a way to simply alter the resource-line or do I have to manually add each route?
This will make all your routes via :photos through p
resources :p, :controller => "photos"
To be more concise and avoid the issue with p_id, you could do it like this :
resources :photos, path: 'p'
This way, you benefits from the readibility on your end (it will generate helpers like edit_photo_path, you will access variables as photo_id in case of a nested route and such) and generate the named URLs you do want.
I have the following route set up. I need to make the index action automatically use the pubmed_search route below.
resources :users do
resources :publications do
collection do
get :pubmed_search
post :pubmed_list
end
end
end
I tried
resources :users do
resources :publications do
collection do
get 'publications', :action => :pubmed_search
get :pubmed_search
post :pubmed_list
end
end
end
Without luck I could just do a redirect in the index method of the controller but i am sure there is a Rails way to do this and I want to learn.
EDIT:
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"
But isn't there a better way, using the RESTful resources?
This works
get "/users/:user_id/publications" => "publications#pubmed_search", :as => "user_publications"
# routes.rb
resource: :users, only: :create, path_names: { create: 'register' }
Following the routing guide at guides.rubyonrails.org, this line is expected to replace /users with /users/register, but the path_names argument seems to have no effect whatsoever. What am I doing wrong?
EDIT:
Interesting that it only applies to new and edit. In any case, this is the work around I used
resource :users, only: :nothing do
post "register", to: :create
end
Done this way to make it slightly easier to enable more actions for users in the future
From rails guide:
The :path_names option lets you override the automatically-generated
"new" and "edit" segments in paths
It seems that you can't rename the create action.
How to make the second route work?
resources :users, only: [:edit, :update]
get ':id', :to => 'users#show', :as =>'user'
Rails gives error because of the second line:
Invalid route name, already in use: 'user' You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here: http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
(Expanding my comment for reference of future viewers.)
Switching the order of the routes will change the precedence, giving the get route preference to the RESTful routes.
From the documentation in a new config/routes.rb:
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".