Rails Password Validate only in certain cases - ruby-on-rails

In my rails 3 application, I have a user sign up form. I have it require and validate the password for signing up, however, if a user connects using omniauth, I cannot retrieve their password which brings me to my question. How can I make it so the password field does not get validated in certain cases?
I am aware that I can do user.save(:validate => false), but that takes off all the validations.
P.S. i watched railscasts episode 235 & 236, however Ryan Bates does it with Devise, and I am doing it with my own login system.

You can write your own validation for password with a check if the user is using oauth.
Check this method: validate(*args, &block)

you can add conditions to the validation in the model:
validates_presence_of :password, :unless => :account_from_omniauth?
assuming you also define the method
def account_from_omniauth?
true if //...your conditions
false
end

Related

How to sign up with devise user and ignore some validations

I have a setup devise for user signup, this is working and so are the password validations that come by default. I have updated that devise model to include other fields like hometown, address, etc. I still want the user to be able to sign up by only providing email and password. When I added validations for fields like address, gender, etc, when a user wants to sign up, it will complain that those fields are empty. How can I ignore specific validations such as address, gender, etc, without ignoring the password validation that came by default? I saw something about using a flag inside .save(:validate => false) but I don't want to use this because it will ignore password validation.
Is there a way to solve this without having to create an additional model? User and UserAdditionalInfo? I want everything in User.
Thanks.
when you add the validation for address, say :allow_blank => true
For eg:
validates_length_of :address, :maximum => 30, :allow_blank => true
This will allow you to create a user without checking the address length.

rails 3.1 partial_updates doesn't seem to work with password

i have a user model with a password attribute, which gets saved as password_digest.
What i want to do is have the edit user page and the edit password page separated, so that
the admin doesn't need to input the password everytime he needs to change something else. For this i have made an extra action / view.
My problem is that when i update the user info, i get password validation errors even though
i have no password field in the form. Which leads me to the conclusion that partial_updates isn't working with the password attribute (as i have already tested in the console that it is enabled, and it is)
Is this me doing something wrong, or should i approach this differently?
Similar to the railscasts approach mentioned by #normalocity, but without the need to set a pseudo-attribute in the controller, we do this (which is essentially taken from restful_authentication):
attr_accessor :password
validates :password,
:length => { :minimum => 8 },
:confirmation => true,
:presence => true,
:if => :password_required?
def password_required?
password_digest.blank? || !password.blank?
end
Basically, we assume that if the password_digest hasn't been set yet (for a new record), or if the password pseudo-attribute has been set, then that means the password is being changed and the validations have to be run. So we don't need to set a updating_password pseudo-attribute like they do in the railscasts episode.
You need to validate the password only if it's being changed. If it's not being changed, then the validation for the password field should be skipped.
Railscasts.com episode #41 shows you how to do this.

How can I use validation rules set in a model in several controllers in ruby on rails?

For the sign-up form for my website I don't require that users confirm their passwords so there isn't a password confirmation field.
However when a user resets their password and they click the link in their email and then taken to a change password page I require they confirm their password and provide a field for them to do this.
My question is how can I add password confirmation and min and max lengths for passwords with out it affecting my sign up form because they use they same model. For my signup form I have min and max length validation rules and want these to apply to the change password form but also include password confirmation.
What is the best and most convenient way to do this in your opinion?
If password confirmation should only be done for users already created, the simplest solution is :
class User < ActiveRecord::Base
validates_confirmation_of :password, :unless => :new_record?
end
So it will only call the validation when setting the value for new users and not for users trying to sign up.
You can create your own methods to validate model data, something like this:
class User < ActiveRecord::Base
validate :user_data_validation
def user_data_validation
errors.add(:password_confirmation, "error in the password confirmation") if
!password.blank? and password != password_confirm
end
end
On the other hand you can use control-level validations, but:
Controller-level validations can be tempting to use, but often become
unwieldy and difficult to test and maintain. Whenever possible, it’s a
good idea to keep your controllers skinny, as it will make your
application a pleasure to work with in the long run. (c)

Rails 3 + devise - email + user creation

I am new to Rails. I am trying to create user management + login system using Devise. All is great except two things:
1) Is there any way to remove "email" field and/or validation when signing up? When remove :validatable from model, then passwords doesn't validate too.
2) What is best way to make user management in system? Something like overriding devise sign up?
I was searching in google for answers and readed documentation, but don't found answers.
Thank you.
1) You should remove :validatable and write your own validation in User model.
2) You can create users by hand in devise:
#user = User.new(:field1 => "something", :field2 => "something else", :password => "secret", :password_confirmation => "secret")
#user.save
if created object passes validation it will be created just like with devise signup action.
You can remove email validation with
def email_required?
false
end
in your User model
1) I don't know from which version onwards, but at least at that time when you where asking your question, there was already a tutorial at the devise github page how to do it.
They outline two ways, one was described here, how to manage that. And you can keep their validations.
2) As for CRUD users they also have a tutorial which is a bit more recent.
Hope this still helps someone ;-)

Authlogic Multiple Password Validation

I'm using Authlogic to manage my user sessions. I'm using the LDAP add-on, so I have the following in my users model
acts_as_authentic do |c|
c.validate_password_field = false
end
The problem is that recently I found out that there will be some users inside the application that won't be part of the LDAP (and can't be added!). So I would need to validate SOME passwords against the database and the others against the LDAP.
The users whose password will be validated against the database will have an specific attribute that will tell me that that password will be validated in my database.
How can I manage that? Is it possible that the validate_password_field receives a "variable"? That way I could create some method that will return true/false depending on where the password validation will be done?
Thanks!
Nicolás Hock Isaza
You should be able to do this:
acts_as_authentic do |u|
u.validate_password_field = true
authentic_options = {:unless => Proc.new{|c| c.ldap}}
u.merge_validates_confirmation_of_password_field_options(authentic_options)
u.merge_validates_length_of_password_confirmation_field_options(authentic_options)
u.merge_validates_length_of_password_field_options(authentic_options)
end
If you were writing the validation yourself (not using authlogic) you would want to do something like this in the validation:
validates_presence_of :password, :unless => Proc.new{|u| u.ldap }
Since authlogic provides the 3 helper methods to add options to the end of the validates methods, you can use this to turn off validations when using LDAP.
You should be able to do an unless in your validation.
acts_as_authentic do |c|
c.validate_password_field = false if c.ldap
end
Or even (as your model field is a boolean) :
acts_as_authentic do |c|
c.validate_password_field = c.ldap
end

Resources