Reputation: 559
I have Devise authentication setup and working, and I've redirected the user to the user's own show page immediately after sign up or login. The user show page and user edit page can be accessed successfully in the browser at:
myapp.com/users/1 and myapp.com/users/1/edit
since I've setup a Users Controller - Now I need to simply take the action in devise that normally occurs at myapp.com/users/edit
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
...which is essentially the edit user account functionality, and I need to make it occur instead at users/:id/edit. When I access the users/1/edit page for my user and update the email or password and click 'update'...the url changes to myapp.com/users/update_account and I get the following error:
Unknown action
The action 'update' could not be found for UsersController
config/routes.rb
devise_for :users
resources :users
resources :users, only: [:edit] do
collection do
patch 'update'
end
end
root 'static_pages#home'
get '/users/:id', :to => 'users#show'
get '/users/:id/edit', :to => 'users#edit'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
rake routes provides:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
users PATCH /users/update(.:format) users#update
GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / static_pages#home
help GET /help(.:format) static_pages#help
My Header Links to the user profile and account settings pages:
views/layouts/_navigation_links.html.erb
<% if user_signed_in? %>
<div class="dropdown"">
<li class="dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<%= current_user.email %>
<span class="caret"></span>
</li>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><%= link_to 'My Profile', user_path %></li>
<li><%= link_to 'Account Settings', edit_user_path %></li>
<li><a href="#">Edit Profile</a></li>
<li role="separator" class="divider"></li>
<li><%= link_to 'Log out', destroy_user_session_path, method: :delete %></li>
</ul>
</div>
<% elsif %>
<li><%= link_to "Sign Up", new_user_registration_path %></li>
<li><%= link_to "Sign In", new_user_session_path %></li>
<% end %>
My Users Controller:
class UsersController < ApplicationController
before_filter :authenticate_user!
def edit
@user = current_user
end
def update
@user = User.find(current_user.id)
if @user.update_with_password(user_params)
# Sign in the user by passing validation in case their password changed
sign_in @user, :bypass => true
redirect_to @user
else
render "edit"
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :current_password)
end
end
My Views/Users/Edit.html.erb
<% provide(:title, "Edit user") %>
<div class="container middle">
<!-- SideBar NEED TO REFACTOR TO A USER LAYOUT FILE -->
<div class="sidebar col-md-3">
</div>
<div class="main-content col-md-9">
<div class="main-breadcrumb">
Some Content
</div>
<div class="section_header">
<h3>Edit Account</h3>
</div>
<div class="row-fluid">
<div class="col-md-6">
<%= form_for(@user, :url => { :action => "update" } ) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<h3>Cancel my account</h3>
# I removed the devise 'cancel account' functionality for now
<%= link_to "Back", :back %>
</div>
</div>
</div><!-- end main content section -->
</div><!-- end Container -->
Any help on how to fix this error would be appreciated.
Upvotes: 0
Views: 563
Reputation: 3006
The browser is sending PATCH /users/update_account
, which looks like what you want. However, the first line in rake routes
that matches is:
PATCH /users/:id(.:format) users#update
... which is not what you want.
You've got resources :users
twice in config/routes.rb; you should only have it once. Try this:
resources :users do
collection do
patch 'update_account'
end
end
This will generate all the standard routes for users
, as your top line currently does, but also /users/update_account
- I think before all the standard ones.
Upvotes: 1