2

我有一个接受银行账户信息和用户信息的支付 api。我捕获了 api 响应并使用 ajax 将信息发送到我的控制器,在那里我尝试将信息保存给我的用户。当我保存时,我收到错误Validation failed: Password can't be blank, Password is invalid:任何想法?

银行控制器:

def addbank
  @user = current_user
  @user.phone_number = params[:phone_number]
  @user.birth_year = params[:year]
  @user.bank_uri = (params['bank_acct_uri'])
  @user.save! # <------- ERROR here!
  # Code was removed to be more clear
end

用户控制器:

def update
  # update user controller has been commented out but the error is still there
end

用户模型:

class User < ActiveRecord::Base
attr_accessible :email,:password,:password_confirmation,:phone_number,:birth_year

      attr_accessor :password
      before_save :encrypt_password
      before_save { |user| user.email = email.downcase }

      VALID_PASSWORD_REGEX = # some reg-expression
      VALID_PHONE = # some reg-expression
      validates_confirmation_of :password
      validates :password, presence: true, format:{  with: VALID_PASSWORD_REGEX }
      validates :phone_number, format: { with: VALID_PHONE }, if: :phone_number
end

编辑:为什么保存用户没有点击我的更新用户控制器?

4

4 回答 4

2

如果您想避免验证某个特定字段(在您的情况下为密码),但您想进行所有其他验证(例如电话号码),您可以执行以下操作:

attr_accessor :skip_password

validates :password, presence: true, format:{  with: VALID_PASSWORD_REGEX }, unless: :skip_password

然后,在您的控制器中,您可以执行以下操作:

def addbank
  @user = current_user
  @user.skip_password = true # We don't want to validate this..
  @user.phone_number = params[:phone_number]
  @user.birth_year = params[:year]
  @user.bank_uri = (params['bank_acct_uri'])
  @user.save! # <------- ERROR here!
  # Code was removed to be more clear
end

这样做需要您自担风险~~

于 2013-11-11T16:59:47.893 回答
1

您可以尝试在不验证的情况下保存:

@user.save(:validate => false)

更新:

if !@user.valid? && @user.errors[:phone_number].any?
  #do not save
else
 @user.save(:validate => false)
end
于 2013-11-11T16:52:36.437 回答
1

您将加密密码存储在哪里?

如果将其存储在其中,password则每次保存时都会失败验证,因为它不等于password_confirmation

我建议将密码放在单独的字段中。

#from the User Model
attr_accessor :password, :password_confirmation

validates_presence_of :password, :on => :create
validates_confirmation_of :password

def password=(password)
    @password = password
    self.password_digest = BCrypt::Password.create(@password, :cost => 14)
end

def authenticate(password)
    BCrypt::Password.new(self.password_digest) == password
end

这样,密码会被散列并保存到 password_digest,并且不会在保存时触发验证错误。

于 2013-11-11T16:53:46.593 回答
0

我会发布这个,因为我大约 95% 确定这是原因,但如果我离开了,我深表歉意。

我相信这是因为用户的密码确实是空白的。如果您查看您的数据库,您会看到一个可能名为 的列encrypted_password,它永远不会通过您的模型直接访问,也不会解密为您的可访问属性passwordpassword_confirmation属性。

为了更新用户,您必须重新输入密码,或使用该save(false)方法(可能有危险)绕过验证。

于 2013-11-11T16:53:37.677 回答