4

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

5 回答 5

1

(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
于 2012-05-11T19:37:25.003 回答
1

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

只需删除passwordpassword_confirmation如果password_confirmation为空白。IE:

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
于 2012-05-11T20:00:35.750 回答
0

我建议为用户身份验证和东西设计。这取自设计源(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
于 2012-05-11T20:07:39.660 回答
0

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

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

首先,您可以: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]告诉它要将错误附加到哪个字段。

于 2013-05-31T19:46:09.897 回答
-1

您只需要添加:on => :createvalidate.

于 2012-10-26T23:58:07.960 回答