Pt-I-1
Iros: Change the views/users/edit.html.erb content to
<h1>Editing user</h1>
<% form_for(@user) do |f| %>
<%= f.error_messages %>
<p>
<label for="user_name">Name: </label>
<%= f.text_field :name, :size =>40 %>
</p>
<p>
<label for="user_password">Password: </label>
<%= f.password_field :password, :size =>40 %>
</p>
<p>
<label for="user_password_confirmation">Confirm: </label>
<%= f.password_field :password_confirmation, :size =>40 %>
</p>
<p>
<%= f.submit "Update" %>
</p>
<% end %>
<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>
gackd:
The method posted by Iros is what I first did. It’s the obvious easy solution. What I’m wondering is: how do you do this in a way that the user has to enter their current password to change their password?
I tried adding a field to edit.html.erb the way shown above but Rails always complained about it. I sort of got it to work with fields_for like this:
<% fields_for :current_password do |f| %>
<%= f.password_field :current_password %>
<% end %>
That ended up in the params has as params:current_password.
That sucks.
I decided to see if I could use User#authenticate with @user.name and that params[][] mess to see if the user’s current password was correct and then update to the new password provided. It was ugly but seemed to work okay.
Any suggestions?
Jinyoung:
To gackd. You can use password_field_tag function.
<p>
<%= label_tag 'Current password' %>:
<%= password_field_tag :current_password, '', :size => 40 %>
</p>
I suggest below additional code to Iros’s one.
In user.rb
class User < ActiveRecord::Base
# ...
validates_presence_of :name, :password
# ...
h4. MarkG
Since you already know the name of the user you’re attempting to edit, it’d be smarter to pre-populate that field…chances are that if you’re editing their account it’s because of a password change, not that they’ve legally changed their name [sure it can happen, but it’s not the most common situation :-) ]
# ...
<p>
<label for="user_name">Name: </label>
<%= f.text_field :name, :size =>40, :value => @user.name %>
</p>
# ...
Grazybom:
Iros’s solution does not work for me, it changes only view layout but nothing happens on the server side. It does not update the hashed_password. Here is my solution. First, I added a new method to the user’s model:
def self.update_user(params,salt)
# params: {name, confirmation_password}
user = {}
unless params[:password_confirmation].blank?
hashed_confirmation_password = User.encrypted_password(params[:password_confirmation],salt)
user[:name] = params[:name]
user[:hashed_password] = hashed_confirmation_password
user[:salt] = salt
end
return user
end
and, second, I changed the update method in users_controller.rb:
def update
@user = User.find(params[:id])
user = User.update_user(params[:user],@user[:salt])
return redirect_to(:action =>:index) if user.blank?
respond_to do |format|
if @user.update_attributes(user)
..............................
Now, it saves an updated password if the field was changed.
But, there is always “but”, I cannot find the way how to make validation working if I add password and password_confirmation fields. If I create a new user User.new() then validation works (name,password), but if I use User.find() it does not work..
syborg:
Let me explain my soution. Possibly there are more efficient ones but the Convention over configuration asks to memorize or have a lot of documentacion and/or experience. It’s not my case.
So, here is what I did:
First, I exactly made a new edit.html.erb as Iro’s one.
Second, I have modified a line and added another in the update method:
def update
@user = User.find(params[:id])
respond_to do |format|
if (@user.update_attributes(params[:user]) if !params[:user][:password].blank?) #modified line
flash[:notice] = "User #{@user.name} was successfully updated."
format.html { redirect_to :action=>:index }
format.xml { head :ok }
else
flash[:notice] = "User #{@user.name} needs a password" # added line
format.html { render :action => "edit" }
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
end
end
end
I suppose it is not the niciest code, more than that, I’m sure there is some better way to do that. But works
BTW, does anybody know why “validate :password_non_blank” in user model doesn’t work here as it did for the ‘new’ action?

