class Member < ActiveRecord::Base include Ext::DeviseConfiguration include Ext::Integrations::Member has_many :memberships belongs_to :organization belongs_to :person validates :organization, :presence => true validates :member_number, :presence => true before_create :set_member_number CURRENT = :current LAPSED = :lapsed PAST = :past NONE = :none scope CURRENT, where("current_memberships_count > 0") scope LAPSED, where("lapsed_memberships_count > 0").where("current_memberships_count = 0") scope PAST, where("past_memberships_count > 0").where("lapsed_memberships_count = 0").where("current_memberships_count = 0") # # devise_invitable needs this otherwise it can't set the :from param in an email # def headers_for(action) case action.to_s when "invitation_instructions" {:from => self.organization.email} else {} end end # # This is always run DJ'd # def count_memberships self.current_memberships_count = self.memberships.current.count self.lapsed_memberships_count = self.memberships.lapsed.count self.past_memberships_count = self.memberships.past.count self.save end handle_asynchronously :count_memberships # # Intentionally did not use a state machine for this for a few reasons # 1) I'm not all that happy with transitions # 2) Can't find another statre machine that I like and is worth the cost of switching to # 3) This works just fine. I prefer calculating state on the fly here because we're couning the memberships # on this member anyway # 4) Determining a lapsed or past member is a touch more complicated than it sounds # A lapsed member is a member with lapsed memberships *and no current memberships* # It's that last bit that makes grabbing all last members quite difficult in SQL # # Note that this method uses the cached values for current_memberships, lapsed_memberships, and past_memberships # def state return CURRENT if self.current_memberships_count > 0 return LAPSED if self.lapsed_memberships_count > 0 return PAST if self.past_memberships_count > 0 return NONE end def self.states [CURRENT, LAPSED, PAST, NONE] end def self.generate_password Devise.friendly_token end def set_member_number self.member_number = MemberNumberGenerator.next_number_for(self.organization) end # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me def active_for_authentication? super && !suspended? end def self.find_by_membership(membership) Member.find_by_email_and_organization_id(membership.item.order.person.email, membership.organization) #TODO: Biggest join ever end # # * Creates (and invites) a member for this membership if one does not already exist # * Attaches that member to the applicable person # def self.for(membership) member = Member.find_by_membership(membership) if member.nil? member = Member.new({:email => membership.item.order.person.email}) member.organization = membership.item.order.organization member.person = membership.item.order.person member.invite! end membership.member = member membership.save member end end