-
Notifications
You must be signed in to change notification settings - Fork 13
/
user.rb
150 lines (131 loc) · 5.28 KB
/
user.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string default(""), not null
# encrypted_password :string default(""), not null
# reset_password_token :string
# reset_password_sent_at :datetime
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :string
# last_sign_in_ip :string
# created_at :datetime not null
# updated_at :datetime not null
# name :string
#
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile
has_many :agreement_letters
has_many :application_letters
has_many :participant_groups
before_create :set_default_role
ROLES = %i[pupil coach organizer admin]
def role?(base_role)
return false unless role
ROLES.index(base_role) <= ROLES.index(role.to_sym)
end
def set_default_role
self.role ||= :pupil
end
def name
return profile.name if profile
email
end
# Returns the events for which the user's application has been accepted
#
# @param none
# @return [Array<Event>] the user's events
def events
accepted_applications = application_letters.where(status: ApplicationLetter.statuses[:accepted])
accepted_applications.collect { |a| a.event }
end
# Returns true iff. user has submitted an application letter for the given event
#
# @param [Event] given_event
# @return [Boolean]
def application_letter_for_event?(given_event)
return !self.application_letter_for_event(given_event).nil?
end
# Returns the application letter the user has submitted for given_event. Returns Nil if no such letter exists.
#
# @param [Event] given_event
# @return [ApplicationLetter, Nil]
def application_letter_for_event(given_event)
return self.application_letters.find{ |letter| letter.event == given_event }
end
#Returns the events, for which a user has not uploaded an agreement letter
#
# @param none
# @return [Array<Event>]
def events_with_missing_agreement_letters
events.select{ |e| (AgreementLetter.where(user_id: self.id, event_id: e.id).blank? and not requires_agreement_letter_for_event?(e))}
end
# Returns true iff. user has submitted an agreement_letter for the given event
#
# @param [Event] given_event
# @return [Boolean]
def agreement_letter_for_event?(given_event)
return !self.agreement_letter_for_event(given_event).nil?
end
# Returns the agreement letter the user has submitted for given_event. Returns Nil if no such letter exists.
#
# @param [Event] given_event
# @return [AgreementLetter, Nil]
def agreement_letter_for_event(given_event)
return self.agreement_letters.find{ |letter| letter.event == given_event }
end
# Returns true iff. user is at least 18 years old at the start date of given_event
#
# @param [Event] given_event
# @return [Boolean]
def requires_agreement_letter_for_event?(given_event)
return self.older_than_required_age_at_start_date_of_event?(given_event, 18)
end
# Returns true iff. the age of user is age or more at the start_date of given_event. Returns false if age of user is unknown.
#
# @param given_event [Event], age [Integer]
# @return [Boolean]
def older_than_required_age_at_start_date_of_event?(given_event, age)
return false unless self.profile
age_at_event_start = self.profile.age_at_time(given_event.start_date)
return age_at_event_start >= age
end
# Returns the number of accepted applications from the user without counting status of current event application
#
# @param [Event] current event (which application status will be excluded)
# @return [Int] of number of currently accepted applications
def accepted_applications_count(event)
ApplicationLetter.where(user_id: id, status: ApplicationLetter.statuses[:accepted])
.where.not(event: event).count()
end
# Returns the number of rejected applications from the user without counting status of current event application
#
# @param current event (which application status will be excluded)
# @return [Int] of number of currently rejected applications
def rejected_applications_count(event)
ApplicationLetter.where(user_id: id, status: ApplicationLetter.statuses[:rejected]).where.not(event: event).count()
end
# Searches all users with last/first_name containing pattern
#
# @param pattern to search for
# @return [Array<User>] all users with pattern in their name
def self.search(pattern)
with_profiles.where("profiles.first_name LIKE ? or profiles.last_name LIKE ?", "%#{pattern}%", "%#{pattern}%")
end
# Provides access to profile information
# and orders users by first, last name and email (if user has no profile)
#
# @return [Array<User>] all users including their profile information
def self.with_profiles()
joins("LEFT JOIN profiles ON users.id = profiles.user_id")
.order('profiles.first_name, profiles.last_name, users.email ASC')
end
end