I am trying to use validates_format_of in my model file to validate an email address. However, I need to enter two regexes for two special cases. Basically, only a few top-level domain names are allowed.
However, it seems according to the source code for validates it only allows one :format key and one set of options as the hash value. Is there a way to use multiple regexes. I have tried the logical operators but it seems to accept only the first one. Also, using two validates method on the same field leads to nothing getting accepted as one violates the other condition
To explain in actual terms, say I want to only emails that are either gmail or yahoo and nothing else. How do I use regexes to represent both and nothing else? This is my gmail code and it works:
validates_format_of :email, :with => (/^([^#\s]+)#((?:gmail+.)+[a-z]{2,})$/i)
How do I change it to include another top level domain name?
validates_format_of :email,
:with => (/^([^#\s]+)#((gmail|yahoo|hotmail)\.+[a-z]{2,})$/i)
something like this?
[a-z] at the end won't capture something like '.com.au' or similar, is that okay?
Also,
. is for single character, you want \. for an actual period
otherwise 'gmailxcom' would be valid
To build upon the answer of #Neet324, you could use:
validates_format_of :email, :with => (/^([^#\s]+)#((\.?\w+)+)$/i)
to capture any email domains, including subdomains and country level top domains.
Related
I defined a custom EachValidator to see if an attribute has leading or trailing whitespace. I know you can add it to the model like so:
validates :name, whitespace: true
But in the controller I want to call just run just the whitespace validator for some form feedback.
I can run it like this:
Validators::WhitespaceValidator.new(attributes: :name).validate_each(obj, :name, obj.name)
Is there a shorter way to call the specific validator? Like you can do user.valid? but that runs all of the validations. I only want the whitespace validator on the name attribute.
Since you did not come here to be told that your idea is bad and people will hate it: here is an idea that you can play with: :on
https://guides.rubyonrails.org/active_record_validations.html#on
validates :name, whitespace: true, on: :preview
and then in the controller:
def something
#model.valid?(:preview)
end
If you want to run the validation also on createand update you can specify something like
on: [:create,:update,:preview]
(Thanks engineersmnky)
Also: I don't think that giving early feedback to users, before they actually save the record is a bad idea if properly implemented.
This feels like trying to solve a problem (leading/trailing whitespace) by creating a new problem (rejecting the object as invalid), and I agree with the comment about this being a brittle strategy. If the problem you want to solve here is whitespace, then solve that problem for the specific attributes where it matters before saving the object; check out
Rails before_validation strip whitespace best practices
I'm getting a lot of submissions to my publicly editable site in different languages, but would like to limit it to just English characters. Is there any simple way to do this? Should I just do a validation with a regex limiting characters, or are there any common issues with that method?
Note: The text will not contain HTML or any other markup. It should just be plain text, maybe with common characters like dashes, dots, etc.
validates :comment, format: { with: [a-zA-Z0-9\s]+, on: :create } - or other action
It sounds like your problem maybe spam, so there are better solutions you can use. If this is true, see the end of this answer for details.
I commented that depends on which languages you want to block. A dozen or more languages use a latin charset, and even more use a latin charset subset. English uses accents too, such as the word naïve. So I do not recommend you try and do this.
If you must, and you want to block none-latin characters, you can write a custom validator.
class LatinCharsetValidator < ActiveModel::EachValidator
# Regex taken from this answer http://stackoverflow.com/a/13671443/276959
LATIN_CHARSET_REGEX = /[\p{L}&&[^a-zA-Z]]/
def validate_each(object, attribute, value)
object.errors.add(attribute) if value =~ LATIN_CHARSET_REGEX
end
end
You can then call this validator in your model as such:
class Comment < ActiveRecord::Base
validates :comment, latin_charset: true
end
This assumes that your users are legitimately trying to comment. If not, you can use the regex to skip the comment creation without providing feedback.
I believe this is a bad idea, though. You can't control what people end up writing or pasting in the text area, and you might end up blocking legitimate comments. What if someone wants to include a foreign word while trying to explain it? It's better to politely ask your users to only comment in English.
If your problem is spam, however, you are better off implementing a honeypot or some other type of spam protection.
I've created a view that has two input's in it, both dates, and I want the user to type them in a specific format. I created it as an index rather than a form, long story. I'm trying to use Regex to validate the date's the user types in. I want the dates to be in the format of YYYY-MM-DD, so if the user types in a date in a different format it causes an error. Should this regex be placed in the controller or in the model? I've tried validates_format_of in the model but it doesn't seem to be working. I'm also on rails 2.3 and ruby 1.8.7.
validates_format_of :date, :with => /^\d{4}-\d{2}-\d{2}$/
you saying validates_format_of doesn't seem to be working. What does it mean? Please give more information.
For acts-as-taggable-on, how do you make Tags be a certain amount of characters? I want users to only be able to have a maximum of 50 characters when they are creating tags.
Thank you.
You can use a validation for this. Try using this in your model. Replace :tag_name with the correct field.
validates_length_of :tag_name, :maximum=>50
Also an awesome reference to rails validations is here.
NOT a Rails 3 issue
In a Contact model I have a company_name attribute. For reasons that don't matter to this question, I want to prohibit an ampersand character. We have a lot of clients with ampersands in their company name, and users forget they aren't allowed to use this character.
This isn't an html sanitize issue. I don't care about whitespace or CDATA or anything. The entries in this field are plain text and I don't want an ampersand to be entered in this one field in any way, shape or form.
I assume a validation on the model is the way to go. I have tried validates_exclusion_of. I have tried validates_format_of. No success. I'm unsophisticated when it comes to regex, so I might be doing things very wrong. But the bottom line is - I need to prevent a user from entering that "&" character in the company_name field.
Thanks a million.
Steve
validates_format_of :company_name, :with => /\A[^&]*\Z/
But probably you could just remove ampersands before saving record:
before_save :strip_ampersands
def strip_ampersands
company_name.gsub!("&", "")
end