8

I am trying to validate an email address.. whether it is present or not.. and whether it meets a regex criteria (/xyz/). I really need to do this on the controller or view level in rails as I am going to be dumping ActiveRecord for my app as I am planning on using a nosql database later.

Any hints? Suggestions?

In the model, it would be the following code.. but I'm trying to do this in controller or view:

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :email, presence: true, 
                    format: { with: VALID_EMAIL_REGEX }, 
                    uniqueness: { case_sensitive: false }
sambehera
  • 959
  • 3
  • 13
  • 33
  • `controller or view level in rails`, do you mean on the client side? If so, this is no longer a Rails question. This is a javascript question. – Jason Kim Apr 03 '13 at 22:51
  • 1
    You do understand that a simple regex will not validate email addresses, don't you? You can pick out what looks like an email address, but whether it is valid or not can't be determined unless you send a message to that address and get a reply by the user at the other end. The pattern you have is nowhere close to handling real-world address as found on the internet these days. See RFC 2822, http://en.wikipedia.org/wiki/Email_address#Valid_email_addresses or http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html – the Tin Man Apr 03 '13 at 23:20
  • Also see "[Using a regular expression to validate an email address](http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address). – the Tin Man Apr 03 '13 at 23:26
  • thanks for the discussion on validating real email addresses.. I will make my app send emails with authorizations soon. – sambehera Apr 03 '13 at 23:44

2 Answers2

15
class UsersController < ApplicationController
  def create
    user = User.new(params[:user])
    if valid_email?(user.email)
      user.save
      redirect_to root_url, :notice => 'Good email'
    else
      flash[:error] = 'Bad email!'
      render :new
    end
  end

private
  def valid_email?(email)
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    email.present? &&
     (email =~ VALID_EMAIL_REGEX) &&
     User.find_by(email: email).empty?
  end
end

However, I would say that validation still belongs in the model, even if it isn't an ActiveRecord-based one. Please take a look at how to use ActiveModel::Validations:

http://api.rubyonrails.org/classes/ActiveModel/Validations.html http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/ http://asciicasts.com/episodes/219-active-model

Unixmonkey
  • 18,485
  • 7
  • 55
  • 78
  • Hello. What does "=~" mean? – kpaul Jan 23 '16 at 01:06
  • 3
    @kpaul `=~` is sometimes called the `equal-tilde`, which can be read as "matches regex". The return value of that result would be the index it matches or nil, but is usually used as a boolean match. That expression could have also been written `email.match(VALID_EMAIL_REGEX)`, but would be just a little slower due to building out and returning a matchdata object. – Unixmonkey Jan 25 '16 at 15:18
4

You can leave it in the model even if you use nosql later on. Just use ActiveModel instead of ActiveRecord. For example, do not inherit from ActiveRecord.

class ModelName
  include ActiveModel::Validations

  attr_accessor :email

  validates :email, presence: true, 
                format: { with: VALID_EMAIL_REGEX }, 
                uniqueness: { case_sensitive: false }
fontno
  • 6,642
  • 6
  • 36
  • 43