Skip to content

Instantly share code, notes, and snippets.

@jonmagic
Last active December 20, 2022 17:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jonmagic/9522641 to your computer and use it in GitHub Desktop.
Save jonmagic/9522641 to your computer and use it in GitHub Desktop.
A handy Rails model for storing emails with a little logic to let a User have multiple email addresses but a single primary address.
class Email < ActiveRecord::Base
# Nope, it's not RFC compliant. F*** that regex.
# http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html
EmailRegex = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i.freeze
before_validation :strip_spaces
# Public: The email address.
# column :address
# Returns a String.
validates :address,
:presence => true,
:length => { :in => 3..254 },
:format => { :with => EmailRegex, :message => "does not look like an email address" },
:uniqueness => { :case_sensitive => false, :message => "is taken" }
# Public: User email address belongs to.
# column :user_id
# Returns a User.
validates :user_id, :presence => true
belongs_to :user
# Public: Email address validation as a service.
#
# Returns a boolean
def self.valid_email_address?(email)
EmailRegex.match(email)
end
# Public: Is this a primary email address?
# column :primary
# Returns a TrueClass or FalseClass.
# TODO: Validate that only one Email#address per User is the primary.
# Public: Set this email as the primary email. Sets primary to false for any
# other emails for this User.
def set_primary
self.class.transaction do
self.class.where(:user_id => user_id, :primary => true).update_all(:primary => false)
self.primary = true
save
end
end
# Internal: Strip all space from the email.
def strip_spaces
self.address = address.strip
end
end
@jpkeane
Copy link

jpkeane commented Dec 29, 2015

Dont know if this will help, but this is how I validated 1 primary email per user:

def _only_1_primary_email_address
return unless user_id && primary
primary_email = UserEmail.where(user_id: user_id, primary: true)
return unless emails.any?
if primary_email.first.primary && primary_email.first.email_address != email_address
errors.add :primary, 'cannot be a second primary'
end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment