【问题标题】:Updating User password & email in separate forms but in same view以不同的形式但在同一视图中更新用户密码和电子邮件
【发布时间】:2015-05-20 15:12:07
【问题描述】:

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

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

更新密码要求用户输入旧密码、新密码并确认新密码,然后点击“更新密码”按钮。问题一定出在 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

edit.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 %>

routes.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 ...)

user.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 ...)

【问题讨论】:

  • 请发布您的更新密码操作日志
  • @AmitSharma 在路由标题下发布的日志是针对 update_pwd 操作的 - 在单击“更新密码”btn 后触发。如您所见,由于某些奇怪的原因,update_email 被调用了。
  • 请将您的日志发布到问题,并使用完整、正确的英文——没有首字母缩略词,没有按钮的 btn。此外,当您已经在标签中添加标签时,通常不赞成在标题中添加标签。
  • Slight type 也是如此,我认为:你在几个地方都有&lt;/br&gt; 而不是&lt;br&gt;
  • @QPaysTaxes 对不起,我不能说我明白你所说的登录问题的意思;我所做的编辑只涉及拼写,现在将 的实例更改为
    。谢谢。

标签: forms validation ruby-on-rails-4 strong-parameters bcrypt-ruby


【解决方案1】:

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

routes.rb

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

edit.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

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2020-10-08
    • 2014-05-24
    • 2013-06-17
    • 2016-02-24
    相关资源
    最近更新 更多