我有4个与用户模型关联的表单,这就是我希望他们表现的方式 -
email, name, password, password_confirmation
email, name
current_password, password, password_confirmation
password, password_confirmation
我最接近的验证解决方案是 -
validates :password, presence: true, length: { minimum: 6 }, on: :update, if: lambda{ |u| u.password.blank? }
这将满足第1,3和4点,但它不允许用户更新属性,即def update
(第2点),因为没有params[:user][:password]
,因此{presence: true}
验证触发了。
当表单包含密码字段时,validate_presence_of :password
,仅的最佳方法是什么?
答案 0 :(得分:4)
试试这个:
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
当且仅当密码字段出现在表单上时,它才会验证密码。
但是这很危险,如果有人从html中删除密码字段,那么这个验证不会触发,因为那样你就不会得到密码的索引。所以你应该这样做:
validates :password, presence: true, length: { minimum: 6 }, if: ->(record) { record.new_record? || record.password.present? || record.password_confirmation.present? }
答案 1 :(得分:1)
要回答您的问题,最好是change_password
和reset_password
控制器操作并在那里进行验证。
首先,让您的模型仅在创建时或在已经输入时验证密码:
validates :password, :presence => true,
:length => { minimum: 6 },
:if => lambda{ new_record? || !password.nil? }
然后,对于您的新控制器操作,有以下几点:
class UsersController < ApplicationController
def change_password
...
if params[:user][:password].present?
@user.update_attributes(params[:user])
redirect_to root_path, notice: "Success!"
else
flash.now.alert "Please enter password!"
render "change_password"
end
end
end
为reset_password做同样的事情,你应该是金色的!
答案 2 :(得分:0)
你可以这样做:
validates: validator_method
def validator_method(params_input)
if params.empty?
...
else
your_logic_her
end
您必须原谅我使用伪代码,但您的想法是创建一个单独的方法来验证而不是使用验证:
答案 3 :(得分:0)
你可以使用devise gem或者看看它的实现。这是源代码 https://github.com/plataformatec/devise