I have now this validate for my User model:
validates :email,
presence: true,
uniqueness: { :case_sensitive => false }
I'd like to add :on create for the uniqueness as users are definitely allowed to update their email by putting the same email!
Should I write it this way? I'm afraid the on:create also applies to the presence:true but it should only apply to the uniqueness validation:
validates :email,
presence: true,
uniqueness: { :case_sensitive => false }, on: :create
I would like to say some logic. Email should be unique and user will be identified by his email. So while update, there is no need to put email field where user can edit the email value. You can make the email field as readonly, so that user can not change it while updating the profile.
And yes, the syntax on: :create is the nice solution for it.
yes it will applied on both you can use separate validation for that
validates :email, presence: true
validates :email, uniqueness: { :case_sensitive => false }, on: :create
Related
Is it possible to validate a field for presence after the initial creation?
I want to make phone number mandatory if the user wants to update their account after signing up.
validates :phone, presence: true, if: .....
if I use on: :update I can no longer authenticate until the field is filled
There are many ways to accomplish this task assuming it is a normal Rails model backed by a DB table. Off the top of my head you can do:
validates :phone,
presence: true,
if: Proc.new{ |model| model.id.present? }
Or more to the point and doesn't fail if you assign an ID before saving:
validates :phone,
presence: true,
if: Proc.new{ |model| model.persisted? }
I have a rails 5 API that has the following validations:
validates :key, presence: true, on: :create
validates :key, uniqueness: true
validates :name, presence: true, on: :create
validates :type, presence: true, on: :create
on: create is used to make sure that the validations do not prevent updates. I would like to add an additional validation to ensure that any of these fields are not made null at any point, like on update or otherwise.
I assume I'll use allow_nil: false somewhere, but I'm not sure where to put it, because I want to make sure that null values are never allowed, not just on create.
There is an AcviteRecord Model named User like this:
class User < ActiveRecord::Base
validates :name, :presence => true
validates :email, :presence => true, :uniqueness => true
validates :plain_password, :presence => true, :confirmation => true
validates :plain_password_confirmation, :presence => true
#...other codes
end
It requires that the update of name and email and the update of password are separated.
When only update name and password, using update or update_attributes will cause password validation which is not needed. But using update_attribute will save name and email without validation.
Are there any ways to update particular fields of model with validation without causing the other fields' validation?
Give it a try, might help
class User < ActiveRecord::Base
validates :name, presence: true
validates :email, presence: true, :uniqueness => true
validates :plain_password, length: { in: 4..255, allow_nil: true }, confirmation: true
validates :plain_password_confirmation, presence: true, if: -> (user){ user.plain_password.present? }
# ......
# ......
end
Apart from this you should reconsider about saving plain_password ;)
You can adjust your validations to only run on create. Requiring confirmation ensures changes on edit are applied.
validates :plain_password,
confirmation: true,
presence: {
on: :create },
length: {
minimum: 8,
allow_blank: true }
validates :plain_password_confirmation,
presence: {
on: :create }
I am assuming you are hashing your passwords, so this would accompany code similar to:
attr_accessor :plain_password
before_save :prepare_password
def encrypted_password( bcrypt_computational_cost = Rails.env.test? ? 1 : 10)
BCrypt::Password.create plain_password, cost: bcrypt_computational_cost
end
private #===========================================================================================================
# Sets this users password hash to the encrypted password, if the password is not blank.
def prepare_password
self.password_hash = encrypted_password if plain_password.present?
end
A better way to handle this is to not include the fields in the rest of the edit form, but rather provide a link to "Change my password". This link would direct to a new form (perhaps in a modal window) which will require the new password, confirmation of the new password, and the old password, to prevent account hijacking.
In your case you can use has_secure_password The password presence is only validated on creation.
I am using this block of code for validating email address. The format of entered email address validates well, but the problem is with the "uniqueness" part - I currently can enter more identic email addresses to the database - how is that possible?
Has something changed in Rails 4 about validations?
class BetaAccess < ActiveRecord::Base
validates_format_of :email,:with => Devise::email_regexp, uniqueness: true
end
Thank you.
Try this:
class BetaAccess < ActiveRecord::Base
validates :email,format: {with: Devise::email_regexp}, uniqueness: true
end
format and uniqueness are different validators, if you want to use in one line, you should use validates method.
validates :email, :format => { :with => Devise::email_regexp }, :uniqueness => true
validates_format_of :email,:with => Devise::email_regexp, uniqueness: true
combines uniqueness into the validation for format. Use the validates syntax
validates :email,format: {with: Devise::email_regexp},
uniqueness: true
Also, use the new ruby syntax for hashes. Kind of neat that way
I want to be able to update my user information without having to have the user set a password each time they edit any other attribute.
My current validations are:
validates :password, presence: true, length: { minimum: 8 }
validates :password_confirm, presence: true
how can I make this conditional? It would be clever to only require these validations if the password and password_confirm attribues were in the params. I could use some idea about how to achieve this. Thanks.
I think this should do it:
validates :password, presence: true, length: { minimum: 8 }
validates :password_confirm, presence: true, :if => Proc.new { |a| a.password_changed? || a.new_record? }
See the docs on ActiveModel::Dirty for more on the _changed? methods. There should be no problem running the presence validation on password every time you change an attribute since this will persist in the DB, so it will always pass (whereas password_confirm will not persist and thus requires a conditional).