【问题标题】:Updating user profile without having to enter the password and confirmation each time无需每次输入密码和确认即可更新用户配置文件
【发布时间】:2012-05-11 19:14:11
【问题描述】:

我正在尝试为我的用户模型创建一个名为 edit_profile 的新页面,以便用户可以编辑他的个人资料(字符串)。我关注http://railscasts.com/episodes/41-conditional-validations

这里是表格(edit_profile.html.erb):

  <%= form_for @user, :html => { :multipart => true } do |f| %>

  <div class="field">
    <%= f.label :profile %><br/>
    <%= f.text_area :profile, :class => "round" %><br />
  </div>

  <div class="actions">
    <%= submit_tag "update", :id => "updateSubmit" %>
  </div>
<% end %>

我遇到的问题是我验证了密码和密码确认的存在。当我加载我的 edit_profile 视图时,即使在我尝试提交新的个人资料之前,我也会不断收到此消息 Password is too short (minimum is 6 characters)

这是我的 users_controller.rb:

def edit_profile
  @user = current_user
  @user.updating_password = false
  @user.save
  @title = "Edit profile"
end

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    flash[:success] = "Account updated."
    redirect_to @user
  else
    @title = "Edit user"
    render 'edit'
  end
end

当我只想在用户模型中编辑我的个人资料属性时,如何绕过密码验证?

谢谢!

其他相关信息:

用户.rb

class User < ActiveRecord::Base
    attr_accessor :password, :updating_password
    attr_accessible :name, :email, :password, :password_confirmation, :photo, 
                    :profile
    before_save :downcase_fields
    before_save :encrypt_password
    validates_presence_of :password, :if => :should_validate_password?
    validates_confirmation_of :password, :if => :should_validate_password?      
    def should_validate_password?
      updating_password || new_record?
    end

    validates :name, :presence => true,
              :name_format => true,  
              :uniqueness => { :case_sensitive => false }          
    validates :email, :presence => true, 
              :email_format => true,
              :uniqueness => { :case_sensitive => false }
    validates :password, 
               #:presence => true,
              #:confirmation => true,
              :length => { :within => 6..40 }
    validates :profile,  :length => { :maximum => 160 }
end

【问题讨论】:

  • 你的用户类是什么样的?
  • @juwiley 在我的帖子中添加了用户模型以及相关信息。

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

鉴于您正在谈论个人资料编辑,即您已经有一个有密码的注册用户,您可能希望有条件地跳过密码更新。

如果password_confirmation 为空,只需删除passwordpassword_confirmation。即:

class UsersController < ApplicationController
  before_filter :skip_password_attribute, only: :update

  ...

  def update
    ...
  end

  private

  def skip_password_attribute
    if params[:password].blank? && params[:password_validation].blank?
      params.except!(:password, :password_validation)
    end
  end
end

【讨论】:

  • 即使我添加了隐藏的表单字段,我仍然收到错误Password can't be blank Password is too short (minimum is 6 characters)
  • 遇到和 hyngyn 一样的问题。
  • 要删除“密码不能为空”和“密码太短(最少6个字符)”,进入用户模型(user.rb文件)并添加“:on = > :create" 用于密码长度和密码存在的两个验证语句(例如 "validates :password_confirmation, :presence => true, :on => :create")。
  • @Alexandra 这不允许用户在注册后将密码更改为不合规的值吗? (编辑:我刚试过这个;是的,确实如此。)
【解决方案2】:

(1) 通常,当@user 是新记录时,form_for 会去创建,当@user 不是新记录时,它会去更新。如果这没有发生,那么,您需要设置 :url,也可能是 :method。

<%= form_for @user, :url => (@user.new_record? ? users_path : user_path(@user),
            :html => (@user.new_record? ? { :multipart => true, :method => :post } : { :multipart => true, :method => :put } do |f| %>

(2) 你要求的是

class User
  validate :validate_password_length

  def validate_password_length
    !new_record? || password.length >= 8
  end
end

但是,这允许新用户创建一个帐户并将密码更改为更短的密码。所以最好做到以下几点:

class User
  validate :validate_password_length

  def validate_password_length
    !password_changed? || password.length >= 8
  end
end

【讨论】:

    【解决方案3】:

    我建议为用户身份验证和东西设计。这取自设计源(https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb):

    validates_presence_of     :password, :if => :password_required?
    validates_confirmation_of :password, :if => :password_required?
    validates_length_of       :password, :within => 6..128, :allow_blank => true
    
    protected
      def password_required?
        !persisted? || !password.nil? || !password_confirmation.nil?
      end
    

    【讨论】:

    • 使用这种方法,即使我添加了隐藏的表单域,我仍然得到错误Password can't be blank Password is too short (minimum is 6 characters)
    【解决方案4】:

    这就是我最终解决此问题的方法,尽管我很确定这并不理想 - 如果您有额外的密码强度规则,验证方法将需要更复杂。

    基本上,您实际上根本不需要更改控制器 - 您可以修复模型来处理这种情况。

    首先,您可以在密码和密码确认字段上设置:on =&gt; :create 属性。但是,这样做的副作用是用户必须在注册时提供符合要求的密码,但以后可以将其更改为不符合要求的密码。为了解决这个问题,我添加了一个before_update 回调来在更新时验证密码字段。我的User 类现在看起来像这样:

    class User < ActiveRecord::Base
      ...
      before_update :check_password
      ...
      validates :password, presence: true,
                           length: { minimum: 6 },
                           on: :create
    
      validates :password_confirmation, presence: true,
                                        on: :create
      ...
      private
        ...
        def check_password
          is_ok = self.password.nil? || self.password.empty? || self.password.length >= 6
    
          self.errors[:password] << "Password is too short (minimum is 6 characters)" unless is_ok
    
          is_ok # The callback returns a Boolean value indicating success; if it fails, the save is blocked
        end
    end
    

    正如上面评论中提到的,这个方法的结果决定了是否会尝试保存。为了防止用户在没有错误消息的情况下被转储到编辑表单中,我注入了一个。 [:password] 告诉它要将错误附加到哪个字段。

    【讨论】:

      【解决方案5】:

      您只需将:on =&gt; :create 添加到validate

      【讨论】:

      • 我建议您提供一些有关需要进行更改的上下文;也许一个代码 sn-p 引用了更​​改应该去哪里?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-28
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 2015-03-21
      • 2021-06-04
      相关资源
      最近更新 更多