Regex, size check inside a Controller's method

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

user model:
INVALID_EMAILS = %w(gmail.com hotmail.com)

But that errors, any ideas? I’m not sure if I’m doing the REGEX
correctly, could use some regex help.

CuriousNewbie wrote in post #976445:

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

user model:
INVALID_EMAILS = %w(gmail.com hotmail.com)

But that errors, any ideas?

And the error you get is…?

I’m not sure if I’m doing the REGEX
correctly, could use some regex help.

Well, your regex seems OK, but you should be doing your validation in
the model, not the controller.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

On Jan 21, 12:05am, CuriousNewbie [email protected] wrote:

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.com hotmail.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.

-T

t.pickett66 wrote in post #976562:

On Jan 21, 12:05am, CuriousNewbie [email protected] wrote:

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.com hotmail.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.

-T

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sent from my iPhone

class User < AR::B
INVALID_EMAILS = %w(gmail.com hotmail.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.com hotmail.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?