Model Validations in my controller

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

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.

raghus wrote:

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

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!

Hi --

raghus wrote:

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

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.

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

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.

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

I sort'a thought I said that... (-;

Hi --

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.

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

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

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.

Hi --

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!"

Hi --

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

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