0

我的目标是创建一个个人资料页面,(登录的)用户可以选择更新他们的电子邮件或密码(以不同的形式,因此不能同时更新),而无需离开该页面。

更新一个人的电子邮件就像输入他们的新电子邮件并点击“保存更改”提交按钮一样简单。

更新一个人的密码需要用户输入他们的旧密码,他们的新密码,并确认他们的新密码,然后点击“更新密码”按钮。问题一定出在 update_pwd 方法中。

users_controller.rb

# ...

def edit # template: edit.html.erb
    @user = User.find(current_user)
end

def update_email
    @user = User.find(current_user)
    if params[:commit] == 'Save Changes'
        if @user.update_attributes(user_params_email)
            redirect_to me_url
            flash[:notice] = "Your changes have been saved"
        else # either invalid or taken
            render :edit
        end
   else 
        render :edit
   end
end

def update_pwd
    @user = User.find(current_user)
    if params[:commit] == 'Update Password' 
        if @user.update_attributes(user_params_pwd) && User.find_by(username: current_user.username).try(:authenticate, params[:current_password])
            redirect_to me_url
            flash[:notice] = "Password updated!"
        else
            flash.now[:alert] = @user.errors.full_messages[0]
            render :edit
        end
    else
        render :edit
    end
end

private

#def user_params
    #params.require(:user).permit(:id, :username, :email, :password, :password_confirmation)
#end

def user_params_email
    params.require(:user).permit(:email)
end

def user_params_pwd
    params.require(:user).permit(:password, :password_confirmation, :current_password)
end

编辑.html.erb

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_email'}) do |f| %>

    <% if @user.errors.any? %>
        <% for message in @user.errors.full_messages %>
            <li><%= message %></li>
        <% end %>
    <% end %>

    <p> Current Email: <%= current_user.email %> </p>
    <p> New Email: <%= f.text_field :email %> </p>

   <%= f.submit "Save Changes" %>

<% end %>

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_pwd'}) do |g| %>

    <p>Old Password<br>
    <%= password_field_tag :current_password, params[:password] %></p>
    <p>New Password<br>
    <%= g.password_field :password %></p>
    <p>Confirm New Password<br>
    <%= g.password_field :password_confirmation %></p>

    <%= g.submit "Update Password" %>
<% end %>

路线.rb

# ...
get '/me' => 'users#edit'
patch '/me' => 'users#update_email'
patch '/me' => 'users#update_pwd'
# ...

现在,我已经能够让电子邮件更新按需要工作(使用必要的错误消息/验证等),但是只要单击更新密码按钮,视图就会呈现,但没有任何反应。相反,似乎正在调用 update_email 函数:

Started PATCH "/me" for ::1 at 2015-05-20 10:34:31 -0500
Processing by UsersController#update_email as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"msEsj6yxfdrbXjjdm6cH3JamrFU8R1EoZ5asmE831GSxLwpiiIW/wmGrr9HiQxFDySJtW5MKK6Ezq9hZaMNFtA==", "current_password"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update Password"}
←[1m←[36mUser Load (0.0ms)←[0m  ←[1mSELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1←[0m  [["id", 2]]
DEPRECATION WARNING: You are passing an instance of ActiveRecord::Base to `find`. Please pass the id of the object by calling `.id`. (called from update_email ...)

用户.rb

# ...

has_secure_password

validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }   
validates_uniqueness_of :email

validates :password, length:{ minimum: 8 }, on: :create
validates :password_confirmation, presence: true, on: :create
# ...

application_controller.rb

# ...
helper_method :current_user

private

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    rescue ActiveRecord::RecordNotFound
end

错误日志(如上所示)

Started PATCH "/me" for ::1 at 2015-05-20 10:34:31 -0500
Processing by UsersController#update_email as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"msEsj6yxfdrbXjjdm6cH3JamrFU8R1EoZ5asmE831GSxLwpiiIW/wmGrr9HiQxFDySJtW5MKK6Ezq9hZaMNFtA==", "current_password"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update Password"}
←[1m←[36mUser Load (0.0ms)←[0m  ←[1mSELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1←[0m  [["id", 2]]
DEPRECATION WARNING: You are passing an instance of ActiveRecord::Base to `find`. Please pass the id of the object by calling `.id`. (called from update_email ...)
4

1 回答 1

0

您可以尝试以下方法,我认为这会有所帮助。如果您遇到任何问题,请返回。

路线.rb

get '/me' => 'users#edit'
patch '/me' => 'users#update_data'

编辑.html.erb

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_data'}) do |f| %>

    <% if @user.errors.any? %>
        <% for message in @user.errors.full_messages %>
            <li><%= message %></li>
        <% end %>
    <% end %>

    <p> Current Email: <%= current_user.email %> </p>
    <p> New Email: <%= f.text_field :email %> </p>

   <%= f.submit 'Save Changes', name: 'update_email' %>

<% end %>

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_data'}) do |g| %>

    <p>Old Password<br>
    <%= password_field_tag :current_password, params[:password] %></p>
    <p>New Password<br>
    <%= g.password_field :password %></p>
    <p>Confirm New Password<br>
    <%= g.password_field :password_confirmation %></p>

    <%= g.submit 'Update Password', name: 'update_password' %>
<% end %>

users_controller.rb

def edit
    @user = User.find(current_user)
end

def update_data
  @user = User.find(current_user)
  if params[:commit] == "update_email"
    if @user.update_attributes(user_params_email)
      flash[:notice] = "Your changes have been saved"
      redirect_to me_url
    else
      render :edit
    end
  elsif params[:commit] == "update_password"
    if @user.update_attributes(user_params_pwd) && User.find_by(username: current_user.username).try(:authenticate, params[:current_password])
      flash[:notice] = "Password updated!"
      redirect_to me_url
    else
      flash.now[:alert] = @user.errors.full_messages[0]
      render :edit
    end
  else 
    render :edit
  end
end

private

def user_params_email
  params.require(:user).permit(:email)
end

def user_params_pwd
  params.require(:user).permit(:password, :password_confirmation, :current_password)
end
于 2015-05-21T15:35:01.040 回答