Dave
Dave

Reputation: 19220

Unable to route to a method in my controller

I’m using Rails 4.2.5. I’m trying to set up my controller so that when a logged in user visits /users/edit, they see my form where they can edit some of their profiles. So in config/routes.rb I have

  resources :users
  …
  get "users/edit" => "users#edit"

then in “app/controllers/users_controller.rb” I have

  def edit
    @user = User.find(session["user_id"])
    render 'edit' 
  end

but when I visit “http://localhost:3000/users/edit” in a browser, I get the error

The action 'show' could not be found for UsersController

It is true I have no “show” method in my controller, but that is not where I want the user to go. I want them going to the edit method.

Upvotes: 2

Views: 126

Answers (3)

Reza mohseni
Reza mohseni

Reputation: 11

You are trying to go to the show action with this link:

http://localhost:3000/users/edit

You have this route for the show action:

GET /users/:id(.:format)    users#show

(:id) is (edit)

Because you have defined first RESTful route:

resources :users 

Which includes all routes listed below:

users_path      GET       /users(.:format)           users#index
                POST      /users(.:format)           users#create
new_user_path   GET       /users/new(.:format)       users#new
edit_user_path  GET       /users/:id/edit(.:format)  users#edit
user_path       GET       /users/:id(.:format)       users#show
                PATCH     /users/:id(.:format)       users#update
                PUT       /users/:id(.:format)       users#update
                DELETE    /users/:id(.:format)       users#destroy

and then

get "users/edit" => "users#edit"

Rails always finds first match. In this case show action of RESTFul routes will be applied:

GET /users/:id(.:format)    users#show

and the other route will be ignored.

Solution: Change the order of the routes. That way edit route will be applied first.

Upvotes: 1

SomeSchmo
SomeSchmo

Reputation: 665

remove get "users/edit" => "users#edit" from your routes, change to resources :users, only: [:edit] (or more if actions you need them), remove the render 'edit' from your controller (default action).

Visit http://localhost:3000/users/1/edit to see the edit page for user_id 1 (there can't be an edit page for all users, you have to specify the id)

Upvotes: -1

Matt
Matt

Reputation: 14038

The problem is that you're mixing a resource route with your own edit method, and "Rails routes are matched in the order they are specified" so it's matching the resources show route users/:id and stopping there.

You need to move your edit route above the resource.

Alternatively, read the linked guide and see if you can add edit as a collection route to the resource, and except the resources edit method. You may also need to except the show method, but it's worth having a play and seeing what you come up with. Routing is an important aspect and worth time to understand.

Upvotes: 0

Related Questions