Model Validations in my controller


#1

Hi,

I have a validation (for my email column of my users table) in my
user.rb model on the lines of:

validates_format_of(:email,:with => /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]
{2,})$/i,:if => Proc.new {|b| not b.email.blank?}, :message =>
“doesn’t look valid (you can leave it blank if you wish)”)

… and it works fine.

Now I want to check the validity of a supplied email address entered
in a separate controller and view - no DB angle there - it just sends
out emails. Is there a simple way that I can call/invoke this check in
that controller? If not, what else is the best way to do it? I don’t
want to even attempt email delivery if the email id is invalid.

Thanks in advance


#2

raghus wrote:

validates_format_of(:email,:with => /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]
{2,})$/i,:if => Proc.new {|b| not b.email.blank?}, :message =>
“doesn’t look valid (you can leave it blank if you wish)”)

… and it works fine.

Now I want to check the validity of a supplied email address entered
in a separate controller and view

Pull the Regexp out and put it into a constant:

VALID_EMAIL = /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i

Use that at both sites. Use it alone with

if email =~ VALID_EMAIL

Warning: If you Google for “regexp email”, you will learn that a regular
expression for a valid email address is darn-near impossible. The
closest
Regexps out there are very long, above a hundred characters. Rexexp
ain’t
perfect, and it ain’t a parser. The only way to actually verify any
e-mail
address is to mail to it, and hope to get a bounce message if it fails.


Phlip
http://www.oreilly.com/catalog/9780596510657/
“Test Driven Ajax (on Rails)”
assert_xpath, assert_javascript, & assert_ajax


#3

raghus wrote:

in a separate controller and view - no DB angle there
I forgot there’s another answer. Your exact question, as stated, doesn’t
need this, but it’s possible:

m = Model.new(:email => ‘foo@bar’)
if m.valid? …

That’s all; just call the same method as .save would have called. And
remember to throw your model object away and not save it.

Again, the style tips: Don’t call more things when you need less
things.
Your model should grow to contain other validations, and these should
not interfere with your email validator. The fixes for that involve
inheritance and/or monkey patching, so please just extract that Regexp
as a
global constant!


Phlip
http://www.oreilly.com/catalog/9780596510657/
“Test Driven Ajax (on Rails)”
assert_xpath, assert_javascript, & assert_ajax


#4

Hi –

On Sat, 7 Jul 2007, Phlip wrote:

… and it works fine.
That’s all; just call the same method as .save would have called. And
remember to throw your model object away and not save it.

You could run into problems there if you have other validations that
the new object doesn’t pass. I’d recommend pulling the email
(quasi- :-)validation out into a separate method, probably a class
method of a class or module designed for that purpose. That way you
don’t hitch its wagon, so to speak, to the specifics of a model that
may or may not really be relevant.

David


#5

don’t hitch its wagon, so to speak, to the specifics of a model that
may or may not really be relevant.

David

I sort’a thought I said that… (-;


Phlip


#6

David

I sort’a thought I said that… (-;

I’m suggesting not instantiating a Model object

I was being polite. I did say that, for the same reasons as you
provided.


Phlip


#7

Hi –

On Sat, 7 Jul 2007, Phlip wrote:

method of a class or module designed for that purpose. That way you
don’t hitch its wagon, so to speak, to the specifics of a model that
may or may not really be relevant.

David

I sort’a thought I said that… (-;

I’m suggesting not instantiating a Model object, but rather doing
something like:

email = “x@y”
if EmailChecker.check(email) …

so that the email checking can be used independent of the model
validation.

David


#8

Hi –

On Sat, 7 Jul 2007, Phlip wrote:

David

I sort’a thought I said that… (-;

I’m suggesting not instantiating a Model object

I was being polite. I did say that, for the same reasons as you provided.

I thought you’d suggested doing:

m = Model.new(:email => ‘foo@bar’)
if m.valid? …

But I’m probably just not getting something.

David


#9

Hi –

On Sat, 7 Jul 2007, Phlip wrote:

I thought you’d suggested doing:

m = Model.new(:email => ‘foo@bar’)
if m.valid? …

Yup. Specifically, Google shouldn’t contain a broken trail to the answer to
the question “how to call the validations without saving?”

I’m glad to have it clarified. That’s several levels of inference
beyond what I was able to calculate on my own :slight_smile:

David


#10

Yup. Specifically, Google shouldn’t contain a broken trail to the answer
to
the question “how to call the validations without saving?”

I’m glad to have it clarified. That’s several levels of inference
beyond what I was able to calculate on my own :slight_smile:

David

I promise I might not do it again…


Phlip


#11

I thought you’d suggested doing:

m = Model.new(:email => ‘foo@bar’)
if m.valid? …

Yup. Specifically, Google shouldn’t contain a broken trail to the answer
to
the question “how to call the validations without saving?”

But I’m probably just not getting something.

“Again, the style tips: Don’t call more things when you need less
things.
Your model should grow to contain other validations, and these should
not interfere with your email validator. The fixes for that involve
inheritance and/or monkey patching, so please just extract that Regexp
as a
global constant!”


Phlip
http://www.oreilly.com/catalog/9780596510657/
“Test Driven Ajax (on Rails)”
assert_xpath, assert_javascript, & assert_ajax


#12

Philip - thanks! And David thanks for the great discussion as well.