Hello, I’m working to create a method in my controller to check an
email to see if the email’s domain is acceptable. I want to prevent
gmail and hotmail for certain reasons. Here’s what I have so far:
controller:
if valid_email_domain(email_address)
# good email domain
else
# bad email domain
end
protected
def valid_email_domain(emailAddy)
reg = Regexp.new ‘/#{User::INVALID_EMAILS.map{|a|
Regexp.quote(a)}.join("|")}/’
return true if emailAddy.scan(reg).size == 0
end
Hello, I’m working to create a method in my controller to check an
email to see if the email’s domain is acceptable. I want to prevent
gmail and hotmail for certain reasons. Here’s what I have so far:
controller:
if valid_email_domain(email_address)
# good email domain
else
# bad email domain
end
protected
def valid_email_domain(emailAddy)
reg = Regexp.new ‘/#{User::INVALID_EMAILS.map{|a|
Regexp.quote(a)}.join("|")}/’
return true if emailAddy.scan(reg).size == 0
end
But that errors, any ideas? I’m not sure if I’m doing the REGEX
correctly, could use some regex help.
First, I agree with Marnen that this should be done in the model but I
disagree that the regexp is formed correctly on a very minor point;
you don’t need to add the ‘/’ inside the quotes when building a new
regexp object i.e. Regexp.new(‘some regexp’) rather than Regexp.new(’/
some regexp/’).
So what I would do in the model is:
class User < AR::B
INVALID_EMAILS = %w(gmail.comhotmail.com)
def self.valid_email?(email)
reg = Regexp.new(INVALID_EMAILS*’|’) # *‘string’ is an alias
for .join(‘string’) use whichever you preffer
matches = reg.match(email)
return matches == 0
end
end
Then in the controller you can do
def some_action
if User.valid_email?(params[:email]) #do stuff
else #do other stuff
end
end
This has the added benefits that you can use this same validation
anywhere in your code and easily add additional conditions to your
validation in a single place.
But that errors, any ideas? I’m not sure if I’m doing the REGEX
correctly, could use some regex help.
First, I agree with Marnen that this should be done in the model but I
disagree that the regexp is formed correctly on a very minor point;
you don’t need to add the ‘/’ inside the quotes when building a new
regexp object i.e. Regexp.new(‘some regexp’) rather than Regexp.new(’/
some regexp/’).
Quite right. I was reading too fast and missed that.
So what I would do in the model is:
class User < AR::B
INVALID_EMAILS = %w(gmail.comhotmail.com)
def self.valid_email?(email)
reg = Regexp.new(INVALID_EMAILS*’|’) # *‘string’ is an alias
for .join(‘string’) use whichever you preffer
matches = reg.match(email)
return matches == 0
end
end
Better yet, do this as a custom validator method.
Then in the controller you can do
def some_action
if User.valid_email?(params[:email]) #do stuff
else #do other stuff
end
end
This has the added benefits that you can use this same validation
anywhere in your code and easily add additional conditions to your
validation in a single place.
Right. And if you do this as a custom validator, then it will run as
part of Rails’ validation routines without even needing that much
controller code.
class User < AR::B
INVALID_EMAILS = %w(gmail.comhotmail.com)
def self.valid_email?(email)
reg = Regexp.new(INVALID_EMAILS*’|’) # *‘string’ is an alias
for .join(‘string’) use whichever you preffer
matches = reg.match(email)
return matches == 0
end
end
A couple additional notes: The logical test (‘matches == 0’) should
actually be ‘matches.size == 0’. Also, unless you are going to change
your INVALID_EMAILS array at runtime you could generate the regexp on
application boot preventing it from having to be created every time
you run the code. This is a premature optimization but it is also a
valid way of doing things. Also you can do the logical test on the
same line turning #valid_email? into a one liner.
So the user class would look something like this now:
class User < AR::B
INVALID_EMAILS = %w(gmail.comhotmail.com)
INVALID_EMAIL_REGEXP = Regexp.new(INVALID_EMAILS*’|’)
def self.valid_email?(email)
return INVALID_EMAIL_REGEXP.match(email).size == 0
end
end
Another note (last one… maybe) you could use empty? instead of size
but you’d have to negate the result i.e.:
return !INVALID_EMAIL_REGEXP.match(email).empty?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.