更新用户配置文件,而无需每次都输入密码和确认

时间:2012-05-11 19:14:11

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

我尝试为我的用户模型创建一个名为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

如果我只想在用户模型中修改个人资料属性,如何绕过密码验证?

谢谢!

其他相关信息:

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

5 个答案:

答案 0 :(得分:1)

(1)通常,当@user是新记录时,form_for将创建,当@user不是新记录时,它将进行更新。如果没有发生这种情况,那么你需要设置:url,也许是:方法。

<%= 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

答案 1 :(得分:1)

鉴于您正在讨论配置文件编辑,即您已经拥有密码的注册用户,您可能希望有条件地跳过密码更新。

如果password为空,只需删除password_confirmationpassword_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

答案 2 :(得分:0)

我建议设计用户auth&amp;东西。这取自设计源(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

答案 3 :(得分:0)

以下是我最终解决这个问题的方法,虽然我很确定它并不理想 - 如果你有额外的密码强度规则,验证方法需要更复杂。

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

首先,您可以在password和password_confirmation字段中设置:on => :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]告诉它将错误附加到哪个字段。

答案 4 :(得分:-1)

您只需将:on => :create添加到validate