Rails Validation Triggers on resetting password - ruby-on-rails

Here is my model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_many :events
has_many :appointments
validates :name, presence: true
validates :name, format: {with: /\A[[:alnum:]]+\z/, message: 'solo se permiten letras y/o numeros' }, if: 'name.present?'
validates :lastname, format: {with: /\A[[:alnum:]]+\z/, message: 'solo se permiten letras y/o numeros' }, if: 'lastname.present?'
validates :lastname, :presence => true
validates :document, :presence => true
validates_numericality_of :document, :on => :create, :message => "no es un numero", if: 'document.present?'
validates :cellphone, :presence => true
validates :cellphone, numericality:{ only_integer: true, message:"no es un numero"}, if: 'cellphone.present?', :on => :create
validates :cellphone, numericality:{ only_integer: true, message:"no es un numero"}, if: 'cellphone.present?', :on => :update
validates :cellphone, format: { with: /\d{11}/, message: "mal formato, deben ser 11 digitos, incluyendo codigo de area" }, if: "cellphone.present?", :on => :create
validates :cellphone, format: { with: /\d{11}/, message: "mal formato, deben ser 11 digitos, incluyendo codigo de area" }, if: "cellphone.present?", :on => :update
validates :phone, :presence => true
validates :phone, numericality:{ only_integer: true, message:"no es un numero"}, if: "phone.present?", :on => :create
validates :phone, format: { with: /\d{11}/, message: "mal formato, deben ser 11 digitos, incluyendo codigo de area" }, if: "phone.present?", :on => :create
validates_format_of :email,:with => Devise::email_regexp, :allow_blank => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
def medic_with_spec
"#{especialidad}, #{name} #{lastname}"
end
def evento_sin
events.where(available: "1")
end
end
as you can see the validation :cellphone has :on => create and :on => update, so my problem is that when i reset my password from an email link and press update with a new password it shows cellphone validations errors since it has :on => update. How can i make this dissappear?
I tried if: 'cellphone.nil?', it works fine because cellphone is obvioulsy blank (reset password only requires password and password confirmation) but when i go to edit account information it wont validate a none-nil value.
Im using devise.
I read this link Validation errors are triggered when I'm trying to reset password , its the exact same problem, but i have no idea how to implement what they said.
Im new on ruby on rails, if some1 can help me with this i have no idea how to implements advance ruby.

you should disable validation if password_confirmation field is not nil (that means that password was changed). Here's a linked topic Skip validation for some members in Devise model during password reset
So, in your case that would be:
validates :cellphone, numericality:{ only_integer: true, message:"no es un numero"}, :if => :not_recovering_password, :on => :update
def not_recovering_password
password_confirmation.nil?
end

Related

Ruby on rails Update

I have User model, it has some validations and they work on create. But when i call any user from database as #user=User.find(1) #user.valid? it returns false. Could you help me?
class User < ActiveRecord::Base
validates :name, :surname, :username, :phone, :role, :gender, :presence => true
validates :password_confirmation, :email_confirmation, :presence => true
validates :username, :email, :uniqueness => true
validates :verified, :bulletin, :inclusion => { :in => [true, false] }
validates :password,:email, :confirmation => true
....
end
I guess you need to add on: :create param for each validations that only need to be run on create.
For example when you're doing #user.valid? I gess you don't want to check if password_confirmation is present.
So in this case it should be:
validates :password_confirmation, :email_confirmation, :presence => true, :on => :create
Hope it helps :)
There is a special validation for this use case, that the user should provide a confirmation, but the confirmation is not stored in the database
validates :email, confirmation: true, :uniqueness => true
validates :password, confirmation: true, ....
This substitutes the validation for :password_confirmation and :email_confirmation, so you need also to remove them.
See the fine rails guides http://guides.rubyonrails.org/active_record_validations.html#confirmation

Devise for Rails - Validate username as email

I followed this guide to use Username and Email in devise authentication, but when I try to create a new user, ie "newusername" with email "new#username.es" I get the validation error "You have to include an # symbol in your email" but refering to username field.
I tried to use a format validation in the user model, but it doesn't solved anything
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:login]
attr_accessor :login
validates_uniqueness_of :username
validates_presence_of :username
validates :username, length: { in: 4..20 }
validates_format_of :username, :with => /\A[-a-z]+\Z/
##### and also
validates :username,
:presence => true,
:uniqueness => { :case_sensitive => false },
:format => { with: /\A[a-zA-Z]+\z/ },
:length => { in: 4..20 }
I couldn't find in Google anyone else that had the same issue.
I'll appreciate your help.

Rspec Validation Tests on update

Good Evening fellow coders,
I'm slowly trying to get with grips Rspec and most of my validation occurs after the user is created as you can see from the validation below, here is the entire validation section so far.
#validations for common attributes
validates :email, presence: true, on: :create, uniqueness: true,
:format => /#/
validates :password, presence: true, on: :create, length: {minimum: 6}
#validations blocks for dev
with_options :if => lambda { |o| o.role_type == "developer" } do |dev|
dev.validates :first_name, presence: true, on: :update
dev.validates :last_name, presence: true, on: :update
dev.validates :languages, presence: true, on: :update
dev.validates :dev_desc, presence: true, on: :update
dev.validates :github, presence: true, on: :update,
:format => URI::regexp(%w(http https github))
dev.validates :stackoverflow, presence: true, on: :update,
:format => URI::regexp(%w(http https stackoverflow))
dev.validates :level, presence: true, on: :update
dev.validates :street, presence: true, on: :update
dev.validates :city, presence: true, on: :update
dev.validates :state, presence: true, on: :update
dev.validates :postcode, presence: true, on: :update
end
#validations block for employer
with_options :if => lambda { |o| o.role_type == "employer" } do |e|
e.validates :company_name, presence: true, on: :update,
uniqueness: true
e.validates :employer_desc, presence: true, on: :update
e.validates :area_of_focus, presence: true, on: :update
e.validates :number_of_employees, presence: true, on: :update
e.validates :street, presence: true, on: :update
e.validates :city, presence: true, on: :update
e.validates :state, presence: true, on: :update
e.validates :postcode, presence: true, on: :update
end
Now I have my current test which is failing below:
it "should not be valid with blank firstname" do
dev.first_name = ' '
dev.should_not be_valid
end
The user is redirected to the edit page if they are not fully valid. I cannot understand why it isn't passing. I twisted it round and changed it to should which passed the test.
Could someone maybe explain why it's passing, here is the block for dev:
let(:dev) { FactoryGirl.create :dev }
Update: Here is my factory, not sure how this would effect the error:
factory :dev, class: User do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
email { Faker::Internet.email }
password "12345678"
password_confirmation "12345678"
role_type "Developer"
dev_desc "New to development but trying to help the community"
github "www.github.com"
stackoverflow "www.stackoverflow.com"
languages "Rails"
level "Junior"
street {Faker::Address.street_address}
city {Faker::Address.city}
state {Faker::Address.state}
postcode {Faker::Address.zip_code}
end
Appreciate your help trying to understand this as validation works manually after sign up.
The validations for first_name are conditional on role being "developer", but your factory sets role to be "Developer", so the validations are not being applied.
Change your validation to
dev.validates :first_name, presence: true, allow_blank: => false, on: :update
By default, presence validation allows empty values

rails password update validation issue

I have the following validation:
validates :password, :presence => true, :confirmation => true, :length => { :within => 6..40 }, :format => { :with => pass_regex }, :unless => :nopass?
Then, when I try to update without password (nopass? is true) the following errors appear:
There were problems with the following fields:
Password is too short (minimum is 6 characters)
Password is invalid
Notice that the :unless works on :presence and :confirmation but not in :lenght or :format.
How could I fix this?
I've had some strange issues with the :confirmation flag as well, which I never figured out, but that's how I solved the problem in my Rails 3.0.x app:
attr_accessor :password_confirmation
validates :password, :presence => true, :length => {:within => PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH}
validate :password_is_confirmed
def password_is_confirmed
if password_changed? # don't trigger that validation every time we save/update attributes
errors.add(:password_confirmation, "can't be blank") if password_confirmation.blank?
errors.add(:password_confirmation, "doesn't match first password") if password != password_confirmation
end
end
I realise this is not an explanation why your code isn't working, but if you're looking for a quick temporary fix - I hope this will help.
You might use conditional validations
class Person < ActiveRecord::Base
validates :surname, :presence => true, :if => "name.nil?"
end

Ruby on Rails Password Validation

So I have interesting password validation requirements:
When a user signs up, I want them to have to type in password and confirm and be between 6..40 (GOT THIS WORKING 100%)
When a user updates their profile, the same validation rules apply (GOT THIS WORKING 100%)
When an admin adds a user, they only have to enter the password once and it should be validated (NOT WORKIG)
When an admin edits a user and the password field is blank, it shouldn't update the password, if they type something, it should be validated. (PARTIAL WORKING)
validates :password, :presence => true,
:confirmation => true,
:length => {:within => 6..40},
:unless => :force_submit
The only cases I can't cover are when an admin adds a user, it is not validated and when an admin edits a user (and types in a password) it is not validated.
the :force_submit is passed in from the admin form, so the password isn't validated. (So the case of an updating empty password works)
Any ideas/magic?
Building slightly on the accepted answer, here's the code that I used in a Rails project at work. (Note: We're using devise to handle user authentication, and devise_invitable to create new users.)
PASSWORD_FORMAT = /\A
(?=.{8,}) # Must contain 8 or more characters
(?=.*\d) # Must contain a digit
(?=.*[a-z]) # Must contain a lower case character
(?=.*[A-Z]) # Must contain an upper case character
(?=.*[[:^alnum:]]) # Must contain a symbol
/x
validates :password,
presence: true,
length: { in: Devise.password_length },
format: { with: PASSWORD_FORMAT },
confirmation: true,
on: :create
validates :password,
allow_nil: true,
length: { in: Devise.password_length },
format: { with: PASSWORD_FORMAT },
confirmation: true,
on: :update
The below seem to meet my requirements...I am actually now requiring a confirmation for all users.. (It makes the view cleaner). But on an update I am allowing blanks.
validates :password, :presence => true,
:confirmation => true,
:length => {:within => 6..40},
:on => :create
validates :password, :confirmation => true,
:length => {:within => 6..40},
:allow_blank => true,
:on => :update
this works for blank password on update action:
validates :password, :presence => true, :on => :update,
:if => lambda{ !password.nil? }
validates :password,
:confirmation => true,
:length => { :minimum => 6},
:if => lambda{ new_record? || !password.nil? }
yet another variant
validates_presence_of :password_digest
validates_length_of :password, minimum: 6, if: Proc.new { |user| user.password.present? }

Resources