Skip to content

Instantly share code, notes, and snippets.

@thenapking
Last active May 18, 2021 09:03
Show Gist options
  • Save thenapking/fc3be19f9f100bb0378e47302b085331 to your computer and use it in GitHub Desktop.
Save thenapking/fc3be19f9f100bb0378e47302b085331 to your computer and use it in GitHub Desktop.
ActiveRecord Validation and Hooks
# Examples of relationships
belongs_to :location, inverse_of: :people, class_name: "Store", required: true, touch: true
has_one :user, inverse_of: :person
has_many :user_locations, through: :user
has_one :person_flag, inverse_of: :person, autosave: true
has_many :pending_change_locations, through: :pending_changes, source: :locations
accepts_nested_attributes_for :ticket_comments, allow_destroy: true
# Scopes
scope :starters, -> {where(empref: nil) }
scope :not_starters, -> { where.not(empref: nil) }
scope :current_employees, -> { includes(:user).where("people.left_at > CURDATE() or people.left_at IS NULL")}
scope :current_employees_and_recent_leavers, -> {where("people.left_at <= '#{2.weeks.from_now}' or people.left_at IS NULL")}
scope :maternity_leave, -> { joins(:jobtitle).merge(Jobtitle.maternity_leave) }
class << self
# This is how to alias a scope!
alias_method :inactive, :leavers
end
# Be ware default scopes
default_scope {order(:from)}
enum ticket_source: [:phone, :email, :yapster, :'walk-in', :zoom]
paginates_per 10
# Delegated methods
delegate :country, :to => :location, :allow_nil => true, :prefix => false
delegate :name, :to => :manager, :allow_nil => true, :prefix => true
# Hooks
after_validation :set_locked
before_save :set_published_at
after_save :create_changerequest, unless: Proc.new { |person| person.changes.count == 0 }
after_create_commit :create_person_flag
# Validations
validates :empref, presence: { message: :starters_immutable }, on: :update
validates :empref, uniqueness: true, numericality: {only_integer: true}, if: :empref
validates :firstname, presence: true, length: { maximum: 60, minimum: 2 }
validates :email, allow_nil: true, allow_blank: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }, length: {maximum: 255, minimum: 3}
validates :phone, allow_nil: true, allow_blank: true, length: {maximum: 30, minimum: 7}
validate :must_have_contact_details #custom method
# you should validate joins, don't forget accept_nested_attributes_for
validates_associated :user
# if you have uniqueness constraints you must validate this. If say each store can have only one opening time on each day, use the below
validates_uniqueness_of :day_id, scope: [:store_detail_id]
#Some examples using the validate_timeliness gem
validates_date :born_at, :before => lambda { 16.years.ago }, :before_message => :minimum_age
validates_date :started_at, :on_or_after => lambda { 3.months.ago }, :on => :create
validates_date :started_at, :before => lambda { Time.zone.now + 3.months }, :on => :create
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment