Reputation:
I am having a rather difficult problem i want to update the user profile only if they submit the current password.I am not using devise.And another post here at stack overflow didn't really help me. This is my User controller code:
class UsersController < ApplicationController
def new
@user = User.new
end
def show
@user = User.find(params[:id])
@user_posts = @user.posts if @user
if @user
if @user_posts
render 'show.html'
else
render 'show.html'
end
else
render file: 'public/404.html', status: 404, formats: [:html]
end
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to root_path
flash[:notice] = "Successfully Signed up :-)"
else
redirect_to signup_path
flash[:notice] = "You didn't sign up successfully :-("
end
end
def edit
@user = User.find(params[:id])
if current_user.id = @user.id
render 'edit'
else
redirect_to @user
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:notice] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
:password == :password_confirmation
private
def user_params
params.require(:user).permit(:user_name, :email, :password, :password_confirmation)
end
end
And this is my user.rb:
class User
has_secure_password
has_many :posts
has_many :comments
def admin?
self.role == 'admin'
end
def moderator?
self.role == 'moderator'
end
end
Please help because I have been working with this for a long time now. And the other solution about this topic here at stack overflow didn't work.
Upvotes: 1
Views: 1231
Reputation: 1716
One way is to use virtual attributes
class User < ActiveRecord::Base
attr_accessor :current_password
end
add the current_password
attribute
to the form
as a text_field
input
def update
@user = User.find params[:id]
if @user.authenticate(update_params[:current_password])
# update the user
# maybe check if the data are valid
@user.update(update_params)
else
flash[:warning] = "Please provide your password"
@user.errors.add :current_password, "invalid"
render :edit
end
end
def update_params
params.require(:user).permit(:current_password, :email)
end
Upvotes: 1
Reputation: 18803
First, you have a problem in your edit
action:
current_user.id = @user.id
That assigns @user.id
to current_user.id
- you wanted ==
to test that it's the correct User
. You should put a similar check on update
, and probably extract it into a before_action
so you can easily apply it anywhere you want to.
To check that the password is present, add it to your form like any other field and then get it out of params
to verify it. That would look something like this:
class UsersController < ApplicationController
def update
encrypted = encrypt(params[:password]) # Using whatever your mechanism is
if encrypted == @user.encrypted_password
# Update the user
else
flash[:notice] = 'Password is required to update user information.'
redirect_to edit_user(path(@user))
end
end
end
Upvotes: 0