Reputation: 327
I have 4 forms associated with the User model, this is how I'd like them to behave -
email, name, password, password_confirmation
email, name
current_password, password, password_confirmation
password, password_confirmation
The closest validation solution I have is -
validates :password, presence: true, length: { minimum: 6 }, on: :update, if: lambda{ |u| u.password.blank? }
This will satisfy points 1, 3 and 4 but it will not allow a user to update attributes i.e. def update
(point 2) because there is no params[:user][:password]
, so the {presence: true}
validation is triggered.
What's the best way to validate_presence_of :password
, only when the form contained a password field?
Upvotes: 3
Views: 2425
Reputation: 884
Just try this:
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
it will validate password if and only if password field will be present on the form.
But this is dangerous, if somebody delete password field from the html then this validation won't trigger because then you will not get params of password.So you should do something like this:
validates :password, presence: true, length: { minimum: 6 }, if: ->(record) { record.new_record? || record.password.present? || record.password_confirmation.present? }
Upvotes: 4
Reputation: 465
You can use devise gem or else see its implementaion. here is the source code https://github.com/plataformatec/devise
Upvotes: 0
Reputation: 507
To answer your question, It seems best to have change_password
and reset_password
controller actions and do your validations in there.
First, have your model validate password only on create or when it's already entered as such:
validates :password, :presence => true,
:length => { minimum: 6 },
:if => lambda{ new_record? || !password.nil? }
Then for your new controller actions, something along the lines of:
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
Do the same for reset_password and you should be golden!
Upvotes: 1
Reputation: 6932
You could do something like this:
validates: validator_method
def validator_method(params_input)
if params.empty?
...
else
your_logic_her
end
You'll have to forgive me for using psuedo-code, but the idea is that you create a separate method to validate instead of using validates:
Upvotes: 0