How to disable has_secure_password validation when a condition is true?

976 views
Skip to first unread message

David M

unread,
Feb 15, 2012, 11:45:16 AM2/15/12
to rubyonra...@googlegroups.com

I have a User model that can save two types of users:

  1. Password-protected users (for this I need has_secure_password)
  2. Facebook users (for this I don't need has_secure_password, but two different fields: provider and uid)

So, when a normal user registers, the model should validate password fields with has_secure_password and validate the presence of the password field:

has_secure_password
validates
:password, presence: true

This works. I have no problem with this.

But when a user wants to register through Facebook, the password is not needed, because provider and uid will be filled instead. The problem is that I don't know how to disable has_secure_password in this case. I have tried this:

has_secure_password
validates
:password, presence: true, unless: :facebook_user?

And this is the facebook_user method:

def facebook_user?
  provider
!= nil && uid != nil
end

But it doesn't work, as it is still complaining about password_digest:

@messages={:password_digest=>["can't be blank"]}

What am I doing wrong? Isn't it possible to disable has_secure_password selectively?

soldier.coder

unread,
Feb 15, 2012, 8:34:36 PM2/15/12
to Ruby on Rails: Talk
Go to RailsCasts.com and read about OmniAuth with devise. Episodes
#235, and #236 I would totally recommend you subscribe to his site,
by the way.

SC



On Feb 15, 11:45 am, David M <idav...@gmail.com> wrote:
> I have a User model that can save two types of users:
>
>    1. Password-protected users (for this I need has_secure_password)
>    2. Facebook users (for this I don't need has_secure_password, but two

David M

unread,
Feb 16, 2012, 2:23:55 AM2/16/12
to rubyonra...@googlegroups.com
Yes, I already watched those screencasts, but I still don't know how to do it.

IAmNan

unread,
Apr 3, 2012, 1:57:47 PM4/3/12
to Ruby on Rails: Talk
Did you ever get a solution to this? My app also allows authentication
outside without the password.

YogiZoli

unread,
Apr 5, 2012, 6:27:30 PM4/5/12
to Ruby on Rails: Talk
Hi,

I haven't tried it but would go for this:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation

You probably didn't used right conditions. To figure it out I always
use Rails console. Create 2 users, a FB and a nonFB and try them out.

bleakwood

unread,
May 28, 2012, 3:07:00 PM5/28/12
to Ruby on Rails: Talk
This does not work with has_secure_password because this module
automatically adds this validation:
validates_presence_of :password_digest

so no matter how you change the condition of validation in your own
model it just doesnt work. The solution I can think of is to write
your own has_secure_password module, you can copy a lot code from the
original from rails. Or use devise instead.


On Apr 5, 6:27 pm, YogiZoli <zoltanp.g...@gmail.com> wrote:
> Hi,
>
> I haven't tried it but would go for this:http://guides.rubyonrails.org/active_record_validations_callbacks.htm...

Mark

unread,
Jul 18, 2012, 6:51:56 PM7/18/12
to rubyonra...@googlegroups.com
I also have dual login types (ldap and manual, the latter using
has_secure_password) and had the same problem.

It might seem like a hack but the simple solution was to just
set a bogus password for the ldap users (in the create method
in my controller). I don't see any security problem with this
since the ldap users cannot login manually using that password.


emerson mauricio freitas de moura

unread,
Apr 17, 2014, 10:28:13 PM4/17/14
to rubyonra...@googlegroups.com, ida...@gmail.com
The solution is as follows:

remove has_secure_password and use traditional method

validates_confirmation_of :password, :unless => :facebook_user?
validates_presence_of     :password_digest, :unless => :facebook_user?

def facebook_user?
        not uid.nil? and not provider.nil?
end

emerson mauricio freitas de moura

unread,
Apr 19, 2014, 1:10:17 AM4/19/14
to rubyonra...@googlegroups.com, ida...@gmail.com
Sorry, missed some details. The complete solution follows

 has_secure_password(validations: false)    
    
 validates_confirmation_of :password, :if => :password_present?
 validates_presence_of     :password, :on => :create, :unless => :facebook_user?
Reply all
Reply to author
Forward
0 new messages