Class: Member
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Member
- Defined in:
- app/models/member.rb
Constant Summary collapse
- CURRENT =
:current
- LAPSED =
:lapsed
- PAST =
:past
- NONE =
:none
Constants included from Ext::Uuid
Class Method Summary collapse
- .find_by_membership(membership, person) ⇒ Object
-
.for(membership, person) ⇒ Object
-
Creates a member for this membership if one does not already exist * Attaches that member to the applicable person * Invites that member if membership.send_email is true * Generates a new qr code if this is a new member * Generates a membership card if this is a new member.
-
- .generate_password ⇒ Object
- .states ⇒ Object
Instance Method Summary collapse
- #active_for_authentication? ⇒ Boolean
-
#attachments_for(action) ⇒ Object
returns an array of attachments in this format: [ [filename, file], [filename, file] ].
-
#count_memberships ⇒ Object
This is always run DJ’d.
- #current_membership_types ⇒ Object
- #generate_pdf ⇒ Object
- #generate_qr_code ⇒ Object
-
#headers_for(action) ⇒ Object
devise_invitable needs this otherwise it can’t set the :from param in an email.
- #member_card_pdf ⇒ Object
- #member_through ⇒ Object
- #member_tickets_purchased_for(event) ⇒ Object
- #set_member_number ⇒ Object
-
#state ⇒ Object
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 state machine that I like and is worth the cost of switching to 3) This works just fine.
Methods included from Ext::S3Link
Methods included from Ext::Uuid
Methods included from Ext::DeviseConfiguration
Class Method Details
.find_by_membership(membership, person) ⇒ Object
128 129 130 |
# File 'app/models/member.rb', line 128 def self.find_by_membership(membership, person) Member.find_by_email_and_organization_id(person.email, membership.organization) #TODO: Biggest join ever end |
.for(membership, person) ⇒ Object
-
Creates a member for this membership if one does not already exist
-
Attaches that member to the applicable person
-
Invites that member if membership.send_email is true
-
Generates a new qr code if this is a new member
-
Generates a membership card if this is a new member
This method CANNOT be run in any synchronous flow
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/models/member.rb', line 145 def self.for(membership, person) member = Member.find_by_membership(membership, person) if member.nil? member = Member.create!({:email => person.email, :organization => membership.organization, :person => person, :password => SecureRandom.hex(32)}, :without_protection => true) member.person.create_address if member.person.address.nil? membership.member = member membership.save member.generate_qr_code member.generate_pdf member.invite! if membership.send_email else membership.member = member membership.save end member end |
.generate_password ⇒ Object
113 114 115 |
# File 'app/models/member.rb', line 113 def self.generate_password Devise.friendly_token end |
Instance Method Details
#active_for_authentication? ⇒ Boolean
124 125 126 |
# File 'app/models/member.rb', line 124 def active_for_authentication? super && !suspended? end |
#attachments_for(action) ⇒ Object
returns an array of attachments in this format: [ [filename, file], [filename, file] ]
45 46 47 48 49 50 51 52 |
# File 'app/models/member.rb', line 45 def (action) case action.to_s when "invitation_instructions" [ ["membership_card.pdf", member_card_pdf] ] else [] end end |
#count_memberships ⇒ Object
This is always run DJ’d
76 77 78 79 80 81 |
# File 'app/models/member.rb', line 76 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 |
#current_membership_types ⇒ Object
61 62 63 |
# File 'app/models/member.rb', line 61 def current_membership_types memberships.current.collect(&:membership_type) end |
#generate_pdf ⇒ Object
171 172 173 174 175 176 177 |
# File 'app/models/member.rb', line 171 def generate_pdf pdf = PdfGeneration.new(self).generate file = Tempfile.new(["#{self.id}", '.pdf']) file << pdf.force_encoding("UTF-8") self.pdf = file self.save end |
#generate_qr_code ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'app/models/member.rb', line 179 def generate_qr_code file = Tempfile.new(['qr-code', '.png']) Ticket::QRCode.new(self, nil).render(file) self.qr_code = file # If we don't save the ticket here, paperclip will leak a file handle. # Even though we close our Tempfile below, paperclip copies that into # another Tempfile, and only closes the handle when the ticket is saved. save file.close end |
#headers_for(action) ⇒ Object
devise_invitable needs this otherwise it can’t set the :from param in an email
33 34 35 36 37 38 39 40 |
# File 'app/models/member.rb', line 33 def headers_for(action) case action.to_s when "invitation_instructions" {:from => self.organization.email} else {} end end |
#member_card_pdf ⇒ Object
54 55 56 57 58 59 |
# File 'app/models/member.rb', line 54 def member_card_pdf file = Tempfile.new(["member#{self.id}", '.pdf']) self.pdf.copy_to_local_file(:original, file) file.rewind file.read end |
#member_through ⇒ Object
132 133 134 |
# File 'app/models/member.rb', line 132 def member_through self.memberships.map{|membership| membership.ends_at}.max end |
#member_tickets_purchased_for(event) ⇒ Object
65 66 67 68 69 70 71 |
# File 'app/models/member.rb', line 65 def member_tickets_purchased_for(event) Ticket.joins(:ticket_type) .joins(:show => :event) .where(:buyer_id => self.person.id) .where('shows.event_id' => event.id) .where('ticket_types.member_ticket = 1') end |
#set_member_number ⇒ Object
117 118 119 |
# File 'app/models/member.rb', line 117 def set_member_number self.member_number = MemberNumberGenerator.next_number_for(self.organization) end |
#state ⇒ Object
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 state 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
96 97 98 99 100 101 |
# File 'app/models/member.rb', line 96 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 |