app/models/member.rb
# == Schema Information
#
# Table name: members
#
# id :integer not null, primary key
# name :string(255)
# bio :text
# created_at :datetime
# updated_at :datetime
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# gen :integer
# major :string(255)
# current :boolean
# slug :string(255)
# email :string(255)
# phone :string(255)
#
# To create a member, all of the fields except the avatar, email, or
# phone must be present.
# * The name must be at least two characters long
# * The gen must be an integer greater than 0
# * The major must also be at least two characters long
# If no avatar is given, an image is provided by http://robohash.org,
# which hashes input to pictures of robots.
#
# Should robohash.org ever close down, there are also regular
# default images available to be used.
# They can be found in
# /public/images/:style/missing.png
class Member < ApplicationRecord
extend FriendlyId
friendly_id :slug_candidates, use: :slugged
validates :name, presence: true, length: { minimum: 2 }
validates :gen, presence: true,
numericality: { only_integer: true, greater_than: 0 }
validates :major, presence: true, length: { minimum: 2 }
validates :bio, presence: true
validates :email, format: { with: /(\A.+@\w+\.\w+\z)|(\A\z)/,
message: 'Please enter a valid email address.' }
validates :phone, phone: { allow_blank: true }
Paperclip.interpolates :slug do |attachment, _style|
attachment.instance.slug
end
# rubocop:disable Style/AlignHash
has_attached_file :avatar, styles: { thumb: '500x500#', full: '500x9999' },
path: '/members/:slug/:attachment/:style/:filename',
url: '/members/:slug/:attachment/:style/:filename',
default_url: '/images/members/:attachment/:style/missing.png',
s3_protocol: :https
# rubocop:enable Style/AlignHash
include DeletableAttachment
validates_attachment_content_type :avatar, content_type: %r{\Aimage/.*\Z}
# Generates a unique slug for a new member based on their name.
# If a member with the same name already exists, adds gen to the end.
# If a member with the same name and gen already exists, uses unique id.
def slug_candidates
[
:name,
[:name, :gen]
]
end
# Return the first name of the member
def first_name
name.split.first
end
# Return the last name of the member
def last_name
name.split.last
end
# Force the phone to be only numbers on input
def phone=(val)
write_attribute(:phone, Phonelib.parse(val).sanitized)
end
# If a phone record exists, return an international form of the number.
def format_phone
if phone
phone = Phonelib.parse(self.phone)
phone.national
end
end
# Returns all current members of the team, ordered by name then gen.
def self.current_members
Member.where(current: true).order('name ASC, gen')
end
# Returns all alumni of the team, ordered by name then gen.
def self.alumni
Member.where(current: false).order('gen DESC, name')
end
# Returns all the members of Generation GEN
def self.gen(gen)
Member.where('gen = ?', gen).order('name ASC')
end
# Returns all of the generations
def self.gens
Member.select(:gen).distinct.order('gen ASC')
end
def self.by_gen(members)
by_gen = {}
members.each do |member|
gen = 'Generation ' + member.gen.to_s
by_gen[gen] ||= []
by_gen[gen] << member
end
by_gen
end
end