New issue I’m dealing with as I develop my first Rails (Ruby as well for that matter) application.
I am using (in that specific order): Devise, Registration, User
After I generated the Registration scaffolding/model, I moved the files from devise/views/registrations to /views/registrations.
After I generated the User scaffolding, I moved edit.html.erb and show.html.erb to /views/users
I am not using a specific admin controller, but I have some code in there that checks the current_user for admin privileges, and if so, I want to give the admin the ability to edit any user’s information, without having to enter a password. So, the form I’m displaying for edit skips the password fields if the current_user is not an admin (and that part is functioning properly).
The edit form displays fine, and the forms’s fields are filled with the user being edited (not current_user) information.
The problem I’m having is that when I hit update, I get error messages telling me that the password is missing, etc.
I suspect that this has something to do with the edit form action (and perhaps something else).
Here’s what I have for form declaration in edit.html.erb (this is the original form declaration, when it was initially created by Devise, and it moved along with the file as I moved it to registrations and then to users view):
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
When I use firebug to see the form’s HTML, this is what I see:
<form id="new_user" class="new_user" method="post" action="/" accept-charset="UTF-8">
If I change registration_path to edit_user_path:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
This is what I get in HTML:
<form id="new_user" class="new_user" method="post" action="/users/user/edit" accept-charset="UTF-8">
In addition, when I try to submit the form here, it tells me:
No route matches [PUT] "/users/user/edit"
In my users_controller.rb, I have the following (I deleted the edit and update methods from the registrations controller):
def edit
@user = User.find(params[:id])
end
def update
respond_to do |format|
if @user.update_attributes(params[:user])
format.html { redirect_to root_url, flash[:notice] = SUCCESSFUL_REGISTRATION_UPDATE_MSG }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
FYI: Here’s what I see when I generate routes:
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
cancel_user_registration GET /cancel(.:format) registrations#cancel
user_registration POST / registrations#create
new_user_registration GET /request_invite(.:format) registrations#new
edit_user_registration GET /edit(.:format) registrations#edit
PUT / registrations#update
Any ideas?
SOLUTION
In my case, and since I’m using update, the solution is to use update_without_password. If instead this is for new and I did not want to require a password, then it would be: save_without_password
def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_without_password(params[:user])
format.html { redirect_to root_url, flash[:notice] = SUCCESSFUL_REGISTRATION_UPDATE_MSG }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
Keep in mind, your user model isn’t anything special just because devise is handling the logic. You can easily make a new controller/views for editing a users profile and give an admin access to it as well. (This is what I do, I don’t like the user having to enter their password to make any change at all)
After that, it’s pretty much the same as any controller/views