In my current ROR project I am using devise pluing for validation. In my change password form validation, I am using the following code in the user model
validates_presence_of :password, :password_confirmation
But I wants to validate is only for an action. I have a function in my user controller named update_password. I found the that I can assign the action as follows:
validates_presence_of :password, :password_confirmation, :on => :update_password
But its not working. Even if the password and password confirmation fields are empty, the form is submitted. Can anyone help me to solve how to set the validation only for a particular action. Will be a great help
Thanks a lot
You can use :validatable option implemented in devise.
Just add to your model
devise :validatable
And set validation options in your config/initializers/devise.rb file
# ==> Configuration for :validatable
# Range for password length. Default is 6..128.
config.password_length = 6..128
# Email regex used to validate email formats. It simply asserts that
# an one (and only one) # exists in the given string. This is mainly
# to give user feedback and not to assert the e-mail validity.
config.email_regexp = /\A[^#]+#[^#]+\z/
Another way is to use your own regexp validations. You can add to your model
validates :password, :format => { :with => /\A[a-zA-Z]+\z/, :message => "Only letters allowed" }
After that you can call #user.valid? in your controller to check that your user instance is correct.
There are many different ways to validate your model.
You can read more about validation and ActiveRecord callbacks in guides: http://guides.rubyonrails.org/active_record_validations_callbacks.html
If you're using devise, there's no need to check for that. It's handle for you by default.
Related
I need create a method the custom validation called findUpperCaseLetter or similar
I have a attribute called password that belongs to the model called User
My method is somewhat similar to the following. The password attribute must have at least a uppercase letter
def findUpperCaseLetter(username)
username.each_char do |character|
return true if character=~/[[:upper:]]/
end
return false
end
I want add this validation to the User model
class User < ActiveRecord::Base
attr_accessible :user_name,:email, :password
validates_presence_of :user_name,:email, :password
validates_uniqueness_of :user_name,:email
????
end
I have already the following regular expreession
validates_format_of :password, :with => /^[a-z0-9_-]{6,30}$/i,
message: "The password format is invalid"
How I modify it for add the following
The password must have at least one uppercase letter
You don't need custom validation to do this, you can use regex to validate the format of password. Add this to your model
validates :password, format: { with: /^(?=.*[A-Z]).+$/, allow_blank: true }
In Rails, you can do this by using format validator, I have added allow_blank: true to make sure when the field is empty it only throws Can't be blank error message and not format validator error message.
The work of this regular expression is to allow the password to be saved in the database only if it contains at least one capital letter. I have created a permalink on rubular, click here http://rubular.com/r/mOpUwmELjD
Hope this helps!
I am building an app where there are users and owners. Owners have many users and every user can belong_to one owner. It's the same model and the associations are built inside the models. The problem is that I want to be able to add and change the field values of them (e.g. user.department) and has_secure_password (password, password_confirmation) prevents me from doing so, as I have to enter a password & confirmation for the values to be persisted.
Can anyone tell me If I can bypass the password+confirmation validation for the owner ?
I am using the rails tutorial by Michael Hartl https://www.railstutorial.org/book/sign_up
has_secure_password validations: false
validates :password, :password_confirmation, :presence => true, :if => :password
Is one way to achieve that.
In my User model I set validations for the password and its confirmation:
validates_presence_of :password, :password_confirmation
I use this for the forms. These attributes are not stored in the database, I am using the authlogic gem.
Now I am trying to make a system to restore forgotten passwords via email. The user inputs his email and the object is retrieved like this:
#user = User.find_by_email(params[:email])
Then, at a certain point in the process the value of a User attribute is set to true meaning that the user forgot his password, so I need to do a #user.save.
And there's the problem. Since password and password_confirmation were never stored, their values are nil. However, the validations come in play and prevent the user from being updated.
Is there any way to skip those particular validations so I can make this work? Or should I do something else? Any help?
You can skip all validations with save(validate: false). You can skip individual validations with the :if or :unless option, for example.
validates_presence_of :password, :password_confirmation, unless: :forgot_password?
def forgot_password?
# return true if the user is in the forgot password process
end
change
validates_presence_of :password, :password_confirmation
to
Assuming your field that is set to true is forgot_password
validates_presence_of :password, :password_confirmation, :unless => Proc.new { |a| a.forgot_password? }
Conditional Validations documentation
I am working on a project and need some help on where to begin. I have three pages
Update User
Create User
Admin User Password Change (like a Hard Reset Password for but only the admin can reset the user's password)
Change Password
On Create User first name, last name, username, password, and password confirmation are mandatory.
On Update User just first name, last name and username are mandatory.
On Admin User Password Change and Change Password, just password and password confirmation are mandatory.
How would you go about doing this? I don't think this is possible through models using validates_presence_of with an if because there are too many scenarios. Any help or guidance would be appreciated. Also, I am pretty new to Rails if you can't already tell.
You can pass conditionals to your validations:
validates :password, :confirmation => true, :presence => true
validates :first_name, :last_name, :username, :presence => true
validate :admin_user_password_change?
Of course you'd have to define what the admin_user_password_change? method would be to determine if it is an admin user changing a password.
UPDATE
The admin_user_password_change? method might be something like:
def admin_user_password_change?
unless self.admin? && self.password.present? && self.password_confirmation.present?
self.errors.add(:admin_password_change, "password and password_confirmation are required.")
end
end
As for How would it communicate with the controller?, it wouldn't directly. But if any of the conditions in the method are false (e.g. self.admin? && self.password.present? && self.password_confirmation.present?), an error will be added to the instance of User and the instance won't save in the controller.
Setting some fields to new values doesn't unset other fields; just because you're only updating some fields in one action doesn't mean the other fields will be unset, so long as they start in a consistent state.
Just add your validations. It will work fine.
You can tell to your validation work only on certain cenarios only using:
The create:
validates :first_name, :last_name, :username, presence: true, on: :create
The update:
validates :password, presence: true, on: :update
Take a look at on.
For validation based on context take a look at Context Validations
My User model contains :name, :email, and :password fields. All 3 have validations for length. An "update account" web page allows the user to update his name and email address, but not password. When submitted, params[:user] is
{"name"=>"Joe User", "email"=>"user#example.com"}
Note there is no "password" key because the form doesn't contain such an input field.
When I call
#user.update_attributes(params[:user])
the password validation fails. However, since I'm not attempting to update the password, I don't want the password validation to run on this update. I'm confused why the password validation is running when params[:user] doesn't contain a "password" key.
Note that I want to have a separate web page elsewhere that allows the user to update his password. And for that submission, the password validation should run.
Thank you.
My application does something like this
attr_accessor :updating_password
validates_confirmation_of :password, :if => should_validate_password?
def should_validate_password?
updating_password || new_record?
end
so you have to model.updating_password = true for the verification to take place, and you don't have to do this on creation.
Which I found at a good railscast at http://railscasts.com/episodes/41-conditional-validations
In your user model, you could just ignore the password validation if it's not set.
validates_length_of :password, :minimum => N, :unless => lambda {|u| u.password.nil? }
Using update_attributes will not change the value of the password if there is no key for it in the params hash.
Validation doesn't run against the changed fields only. It validates existing values too.
Your validation must be failing because the password field contains some invalid content that's already saved in the database. I'm guessing it's probably because you're hashing it after validation and you're trying to validate the hashed string.
You can use a virtual attribute (an instance variable or method) that you validate with a custom method, and then assign the hash to the stored password field. Have a look at this technique for ideas.
An app that I am working on uses the following:
validates_confirmation_of :password,
:if => Proc.new { |account|
!account.password.blank?
|| !account.password_confirmation.blank?
|| account.new_record? }
Depending on your requirements, you might want to remove the new_record? check
When password is added then only confirmation will be called and presence will call on create action only
**validates_presence_of :password, :on =>:create**
**validates_confirmation_of :password**