-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathuser.rb
More file actions
150 lines (129 loc) · 5.49 KB
/
user.rb
File metadata and controls
150 lines (129 loc) · 5.49 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
# frozen_string_literal: true
# Represents a user in the application. Users are shared across all instances.
class User < ApplicationRecord
SYSTEM_USER_ID = 0
DELETED_USER_ID = -1
include UserSearchConcern
include TimeZoneConcern
include Generic::CollectionConcern
model_stamper
acts_as_reader
mount_uploader :profile_photo, ImageUploader
enum :role, { normal: 0, administrator: 1 }
AVAILABLE_LOCALES = I18n.available_locales.map(&:to_s)
class << self
# Finds the System user.
#
# This account cannot be logged into (because it has no email and a null password), and the
# User Authentication Concern explicitly rejects any user with the system user ID.
#
# @return [User]
def system
@system ||= find(User::SYSTEM_USER_ID)
raise 'No system user. Did you run rake db:seed?' unless @system
@system
end
# Finds the Deleted user.
#
# Same as the System user, this account cannot be logged into.
#
# @return [User]
def deleted
@deleted ||= find(User::DELETED_USER_ID)
raise 'No deleted user. Did you run rake db:seed?' unless @deleted
@deleted
end
end
validates :email, :encrypted_password, absence: true, if: :built_in?
validates :name, length: { maximum: 255 }, presence: true
validates :role, presence: true
validates :time_zone, length: { maximum: 255 }, allow_nil: true
validates :reset_password_token, length: { maximum: 255 }, allow_nil: true,
uniqueness: { if: :reset_password_token_changed? }
validates :locale, inclusion: { in: AVAILABLE_LOCALES }, allow_nil: true
has_many :emails, -> { order('primary' => :desc) }, class_name: 'User::Email',
inverse_of: :user, dependent: :destroy
# This order need to be preserved, so that :emails association can be detected by
# devise-multi_email correctly.
include UserAuthenticationConcern
has_one :primary_email, -> { where(primary: true) }, class_name: 'User::Email', inverse_of: :user
has_many :instance_users, dependent: :destroy
has_many :instances, through: :instance_users
has_many :identities, dependent: :destroy, class_name: 'User::Identity'
has_many :activities, inverse_of: :actor, dependent: :destroy, foreign_key: 'actor_id'
has_many :notifications, dependent: :destroy, class_name: 'UserNotification',
inverse_of: :user do
include UserNotificationsConcern
end
has_many :course_enrol_requests, dependent: :destroy, class_name: 'Course::EnrolRequest',
inverse_of: :user
has_many :course_users, dependent: :destroy
has_many :courses, through: :course_users
has_many :todos, class_name: 'Course::LessonPlan::Todo', inverse_of: :user, dependent: :destroy
has_many :question_bundle_assignments, class_name: 'Course::Assessment::QuestionBundleAssignment',
inverse_of: :user, dependent: :destroy
has_one :cikgo_user, dependent: :destroy, inverse_of: :user
accepts_nested_attributes_for :emails
scope :ordered_by_name, -> { order(:name) }
scope :human_users, -> { where.not(id: [User::SYSTEM_USER_ID, User::DELETED_USER_ID]) }
scope :active_in_past_7_days, (lambda do
where(id: InstanceUser.unscoped.active_in_past_7_days.select(:user_id).distinct)
end)
scope :with_email_addresses, (lambda do |email_addresses|
includes(:emails).joins(:emails).
where('user_emails.email IN (?) AND user_emails.confirmed_at IS NOT NULL',
email_addresses)
end)
# Gets whether the current user is one of the the built in users.
#
# @return [Boolean]
def built_in?
id == User::SYSTEM_USER_ID || id == User::DELETED_USER_ID
end
# Pick the default email and set it as primary email. This method would immediately set the
# attributes in the database.
#
# @return [Boolean] True if the new email was set as primary, false if failed or next email
# cannot be found.
def set_next_email_as_primary
return false unless default_email_record
default_email_record.update(primary: true)
end
# Update the user using the info from invitation.
#
# @param [Course::UserInvitation|Instance::UserInvitation]
def build_from_invitation(invitation)
self.name = invitation.name
self.email = invitation.email
skip_confirmation!
case invitation.invitation_key.first
when Course::UserInvitation::INVITATION_KEY_IDENTIFIER
build_course_user_from_invitation(invitation)
when Instance::UserInvitation::INVITATION_KEY_IDENTIFIER
@instance_invitation = invitation
end
end
def build_course_user_from_invitation(invitation)
course_users.build(course: invitation.course,
name: invitation.name,
role: invitation.role,
phantom: invitation.phantom,
timeline_algorithm: invitation.timeline_algorithm ||
invitation.course&.default_timeline_algorithm,
external_id: invitation.external_id,
creator: self,
updater: self)
end
private
# Gets the default email address record.
#
# @return [User::Email] The user's primary email address record.
def default_email_record
valid_emails = emails.confirmed.each.select do |email_record|
!email_record.destroyed? && !email_record.marked_for_destruction?
end
result = valid_emails.find(&:primary?)
result ||= valid_emails.first
result
end
end