This repository was archived by the owner on Jun 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 137
Expand file tree
/
Copy pathuser.rb
More file actions
241 lines (190 loc) · 6.01 KB
/
Copy pathuser.rb
File metadata and controls
241 lines (190 loc) · 6.01 KB
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# frozen_string_literal: true
require 'github/user'
class User < ApplicationRecord
include EmailPreferences
TSHIRT_SIZES = %w(XXS XS S M L XL 2XL 3XL)
TSHIRT_CUTS = %w(Straight Fitted)
URL_PREFIX_PATTERN = /\A(http|https).*\z/i
ORDERS = {
name: 'LOWER(users.name)',
team: 'teams.name',
github: 'users.github_handle',
irc: 'COALESCE(users.irc_handle, '')',
location: 'users.location',
interested_in: 'users.interested_in',
country: 'users.country',
}
INTERESTS = {
'pair' => 'Finding a pair',
'coaches' => 'Finding coaches',
'project' => 'Finding a project',
'coaching' => 'Helping as a coach',
'mentoring' => 'Helping as a mentor for a project that I am part of',
'helpdesk' => 'Helping as a remote coach (helpdesk)',
'organizing' => 'Helping as an organizer',
'coachingcompany' => 'Providing a coaching team from our company',
}
include ActiveModel::ForbiddenAttributesProtection
include Authentication::ActiveRecordHelpers
include ProfilesHelper
devise :omniauthable, :confirmable
has_many :roles do
def admin
where(name: Role::ADMIN_ROLES)
end
def mentor
where(name: 'mentor')
end
def organizer
where(name: 'organizer')
end
def reviewer
where(name: 'reviewer')
end
def supervisor
where(name: 'supervisor')
end
def student
where(name: 'student')
end
end
has_many :teams, -> { distinct }, through: :roles
has_many :application_drafts, through: :teams
has_many :applications, through: :teams
has_many :todos, dependent: :destroy
has_many :comments, dependent: :destroy
has_one :postal_address, dependent: :destroy
validates :github_handle, presence: true, uniqueness: { case_sensitive: false }
validates :homepage, format: { with: URL_PREFIX_PATTERN }, allow_blank: true
validate :immutable_github_handle
validates :name, :email, :country, :location, presence: true, unless: :github_import
accepts_nested_attributes_for :roles, allow_destroy: true
accepts_nested_attributes_for :postal_address, allow_destroy: true, reject_if: :all_blank
def postal_address_rejectable?(attr)
attr['address_line_1'].blank? || attr['city'].blank? || attr['postal_code'].blank? || attr['country'].blank?
end
before_save :normalize_location
after_create :complete_from_github
# This field is used to skip validations when creating
# a preliminary user, e.g. when adding a non existant person
# to a team using the github handle.
attr_reader :github_import
# This informs devise that this user does not
# need a confirmation notification for now
def github_import=(import)
skip_confirmation_notification! if import
@github_import = import
end
class << self
def ordered(order = nil, direction = 'asc')
direction = direction == 'asc' ? 'ASC' : 'DESC'
if order
order = ORDERS.fetch(order.to_sym) { ORDERS.fetch(:name) }
else
order = ORDERS.fetch(:name)
end
scope = order("#{order} #{direction}").references(:teams)
scope = scope.joins(:teams).references(:teams) if order == :team
scope
end
def with_role(*names)
joins(:roles).references(:roles).where('roles.name' => names.flatten)
end
def with_assigned_roles
joins(:roles).references(:roles).where('roles.id IS NOT NULL')
end
def with_teams
joins(:teams).references(:teams)
end
def with_team_kind(kind)
joins(:teams).references(:teams).where('teams.kind' => kind)
end
def with_all_associations_joined
includes(:roles).group("roles.id").
includes(roles: :team).group("teams.id")
end
def with_interest(interest)
where(":interest = ANY(interested_in)", interest: interest)
end
def immutable_attributes
[:github_handle]
end
def search(search)
q_user_names = User.where("users.name ILIKE ?", "%#{search}%")
q_team_names = User.with_teams.where("teams.name ILIKE ?", "%#{search}%")
(q_user_names + q_team_names).uniq
end
end # class << self
def rating(type = :mean, options = {})
Rating::Calc.new(self, type, options).calc
end
def just_created?
!!@just_created
end
def name_or_handle
name.presence || github_handle
end
def admin?
roles.admin.any?
end
def mentor?
roles.mentor.any?
end
def project_maintainer?
Maintainership
.where(user: self)
.joins(:project)
.merge(Project.accepted)
.any?
end
def reviewer?
roles.reviewer.any?
end
def supervisor?
roles.supervisor.any?
end
def student?
roles.student.any?
end
def current_student?
roles.joins(:team)
.merge(Team.in_current_season)
.merge(Team.accepted)
.student.any?
end
def interested_in_list
interested_in.reject(&:blank?).join(', ')
end
def tech_expertise_list
tech_expertise.join(', ')
end
def tech_expertise_list=(tech_expertise_list)
self.tech_expertise = tech_expertise_list.split(',').map(&:strip).reject(&:blank?)
end
def tech_interest_list
tech_interest.join(', ')
end
def tech_interest_list=(tech_interest_list)
self.tech_interest = tech_interest_list.split(',').map(&:strip).reject(&:blank?)
end
protected
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end
private
# normalization to prevent duplication, NULL for sorting
def normalize_location
self.location = location.to_s.strip.downcase.titlecase.presence
end
def complete_from_github
attrs = Github::User.new(github_handle).attrs rescue {}
attrs[:name] = github_handle if attrs[:name].blank?
attrs = attrs.select { |key, value| send(key).blank? && value.present? }
update_attributes attrs
@just_created = true
end
def immutable_github_handle
return if new_record?
errors.add(:github_handle, "can't be changed") if changes_include?(:github_handle)
end
end