Rails validators: Only show certain messages based on hierarchy - ruby-on-rails

For an email attribute, I have two validator helpers like so:
validates :email,
presence: true,
format: { with: /some_regex/, message: "Bad email error message"}
Is there a way to set this up (without using custom validator methods) so if presence: true fails, it will not display the format message?
I don't want to display a format message when the field is blank...it doesn't present a nice user experience "of course it's a bad format... there's nothing there!"

Use the unless option and remove the presence option.
validates :email,
format: { with: /some_regex/, message: "Bad email error message"},
unless: "email.nil?"
This way, the email will be validated unless the email is nil
Learn more about :if and :unless in the Rails Validation Docs
Alternatively, you can use allow_blank which will ensure that the validation only occurs if the field is not blank.
validates :email,
format: { with: /some_regex/, message: "Bad email error message"},
allow_blank: true
Both do pretty much the same thing. The first option, however, is a little more flexible.

Related

Is there something like .NET's data annotations in rails?

I was looking for something similar to .net's data annotations in rails, something like this.
What I want to achieve by this is: I have some fields (they could be nil also) for which I want to check the length and if the length exceeds I want to display an error message.
I want to club all the error messages related to, say all blog posts (which again have many separate fields) and then display them at once.
Rails uses ActiveRecord validations. In many cases the default validations are easy to set up. But if you want/or need customized validations that can all be done as well. Read the documentation here:
http://guides.rubyonrails.org/active_record_validations.html
In your case this type of validation is built in to rails so it's simple as adding 1 line to your model:
class MyModel
validates :my_field_name, length: { maximum: 3 }, allow_blank: true
end
This will validate the maximum length of your field. You can also customize the validation error message:
class MyModel
validates :name, presence: {message: "Title can't be blank." }, uniqueness: {message: "Title already exists."}, length: { maximum: 5, message: "Must be less than 5 characters"}
end

How to set error message in base in rails' built in validation methods [duplicate]

This question already has answers here:
Rails override validation message
(4 answers)
Closed 6 years ago.
In rails' built in validation methods like:
validates :email, presence: true
and
validates_uniqueness_of :email, message: " address used "
If error occurs, the msg will be: "Email is taken"(default) and "Email address used". But I want a message like "This email address has been taken". I can do this in custom validation functions using 'errors.add(:base, "message")'. I do not know how to set the msg to 'base' like that in a built in validation.
Try
validates :email, presence: true, uniqueness:{message: "custom message"}
You can try this one, let me know i have not tested it. Also really good documentation about validations LINK.
validates :email, presence: true, uniqueness: {case_sensitive: false,
message: "This email %{value} address used" }

How to confirm (not verify) an email address with devise in Rails 4?

I'm using devise and I'm trying to add an email_confirmation input, I want my users to type their email address twice in order to make sure that they didn't make any mistake (like the password_confirmation input). I have searched for a solution for days but all I can find is how to "verify" an email address. How would the validation work ? Any answer/suggestion will be greatly appreciated.
To confirm their email address, add the field email_confirmation to the form:
run rails generate devise:views so that devise views are available within the application.
add email_confirmation to the devise form.
Then allow this parameter to be passed to devise:
https://github.com/plataformatec/devise#strong-parameters
The last step is to add the validation to User model (or the model you use with devise):
validates :email, confirmation: true
You'll want to use a regular expression validation. Something like this should do the trick:
validates :email,
format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, message: 'Invalid email' }
That's assuming that by "verify" you mean simply "check that the thing the user entered looks like a valid email".
There's an additional step of verification, not taken by most apps, which checks that the email not only looks like a valid email, but actually is an email address that exists in real life. If that's what you're after, check out https://github.com/kamilc/email_verifier
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }

Devise Model Shoulda Validation: Email can't be blank (I'm not testing Email)

I got a Devise model called Candidate.
And I got this test:
it { expect(subject).to validate_presence_of(:democracyengine_recipient_id) }
And this line in the model:
validates :democracyengine_recipient_id, presence: true
And the validation works (in other tests).
But in this particular test I get this error:
Failure/Error: it { expect(subject).to validate_presence_of(:democracyengine_recipient_id) }
Expected errors to include "can't be blank" when democracyengine_recipient_id is set to nil, got errors: ["email can't be blank (\"\")", "password can't be blank (nil)"]
How do I fix it?
presence: true is an ActiveRecord validator and in my opinion it should have been called as below : (NOTE: validates and not validate)
validates :democracyengine_recipient_id, presence: true
validate method adds a validation method or block to the class. This is useful when overriding the validate instance method becomes too unwieldy and you're looking for more descriptive declaration of your validations.
See more details in API Documentation for validate
For validates see official API Documentation for validates

Validating presence with rspec

This is my first time testing in rails and I'm having trouble with what I think should be a pretty simple validation.
In group_spec.rb
it { should validate_presence_of(:enc_key) }
it { should validate_uniqueness_of(:enc_key).case_insensitive }
In my model
validates :enc_key, :presence => true, uniqueness: {:case_sensitive => false}
When I run rspec I'm getting
2) Group should require enc_key to be set
Failure/Error: it { should validate_presence_of(:enc_key) }
Expected errors to include "can't be blank" when enc_key is set to nil, got errors: ["owner There is no owner associated with this group. (nil)", "name can't be blank (nil)", "name is
too short (minimum is 4 characters) (nil)", "stripped_name can't be blank (nil)"]
The list of errors are generated from other validations and I've tried writing a custom validation but that didn't work either.
I'm guessing you are using shoulda matchers here and I can't see anything wrong with your test.
I think you should be using the validates method rather than the validate method in you model. validates is used to declare the kind of validation rules that you are specifying here. validate is used to declare custom validations.
So try this in your model:
validates :enc_key, presence: true, uniqueness: {case_sensitive: false}
See http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates
and http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate
The shoulda matchers are designed to work with otherwise valid records. They change various aspects of the record and test that the validation reports the appropriate error. If there are already errors in the record, this approach generally doesn't work.
You haven't shown the rest of your spec, but I gather than subject is nil. You need to set subject to be a valid instance of your record.
See https://github.com/thoughtbot/shoulda-matchers/issues/365 for a related discussion of this.

Resources