Class: Exam

Inherits:
ApplicationRecord show all
Includes:
FriendlyName, GuideContainer, TerminalNavigation
Defined in:
app/models/exam.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TerminalNavigation

#friendly, #navigable_name, #navigation_end?

Methods included from FriendlyName

#friendly_name, #to_param

Methods included from GuideContainer

#friendly, #index_usage!

Methods inherited from ApplicationRecord

aggregate_of, all_except, defaults, #delete, #destroy!, numbered, organic_on, resource_fields, #save, #save_and_notify!, #save_and_notify_changes!, serialize_symbolized_hash_array, #update_and_notify!, update_or_create!, whitelist_attributes

Class Method Details

.adapt_json_values(exam) ⇒ Object



123
124
125
126
127
128
# File 'app/models/exam.rb', line 123

def self.adapt_json_values(exam)
  exam[:guide_id] = Guide.find_by(slug: exam[:slug]).id
  exam[:organization_id] = Organization.current.id
  exam[:users] = exam[:uids].map { |uid| User.find_by(uid: uid) }.compact
  [:start_time, :end_time].each { |param| exam[param] = exam[param].to_time }
end

.import_from_resource_h!(json) ⇒ Object



112
113
114
115
116
117
118
119
120
121
# File 'app/models/exam.rb', line 112

def self.import_from_resource_h!(json)
  exam_data = json.with_indifferent_access
  organization = Organization.find_by!(name: exam_data[:organization])
  organization.switch!
  adapt_json_values exam_data
  remove_previous_version exam_data[:eid], exam_data[:guide_id]
  exam = where(classroom_id: exam_data[:eid]).update_or_create!(whitelist_attributes(exam_data))
  exam.process_users exam_data[:users]
  exam
end

.remove_previous_version(eid, guide_id) ⇒ Object



130
131
132
133
134
135
136
# File 'app/models/exam.rb', line 130

def self.remove_previous_version(eid, guide_id)
  Rails.logger.info "Looking for"
  where("guide_id=? and organization_id=? and classroom_id!=?", guide_id, Organization.current.id, eid).tap do |exams|
    Rails.logger.info "Deleting exams with ORG_ID:#{Organization.current.id} - GUIDE_ID:#{guide_id} - CLASSROOM_ID:#{eid}"
    exams.destroy_all
  end
end

Instance Method Details

#accessible_for?(user) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'app/models/exam.rb', line 47

def accessible_for?(user)
  authorized?(user) && enabled_for?(user)
end

#attempts_left_for(assignment) ⇒ Object



138
139
140
# File 'app/models/exam.rb', line 138

def attempts_left_for(assignment)
  max_attempts_for(assignment.exercise) - (assignment.attempts_count || 0)
end

#authorization_for(user) ⇒ Object



67
68
69
# File 'app/models/exam.rb', line 67

def authorization_for(user)
  authorizations.find_by(user_id: user.id)
end

#authorizations_for(users) ⇒ Object



71
72
73
# File 'app/models/exam.rb', line 71

def authorizations_for(users)
  authorizations.where(user_id: users.map(&:id))
end

#authorize!(user) ⇒ Object



55
56
57
# File 'app/models/exam.rb', line 55

def authorize!(user)
  users << user unless authorized?(user)
end

#authorized?(user) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
# File 'app/models/exam.rb', line 59

def authorized?(user)
  users.include? user
end

#clean_authorizations(users) ⇒ Object



104
105
106
# File 'app/models/exam.rb', line 104

def clean_authorizations(users)
  authorizations.all_except(authorizations_for(users)).destroy_all
end

#enabled?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'app/models/exam.rb', line 22

def enabled?
  enabled_range.cover? DateTime.now
end

#enabled_for?(user) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
# File 'app/models/exam.rb', line 30

def enabled_for?(user)
  enabled_range_for(user).cover? DateTime.now
end

#enabled_rangeObject



26
27
28
# File 'app/models/exam.rb', line 26

def enabled_range
  start_time..end_time
end

#enabled_range_for(user) ⇒ Object



63
64
65
# File 'app/models/exam.rb', line 63

def enabled_range_for(user)
  start_time..real_end_time(user)
end

#in_progress_for?(user) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'app/models/exam.rb', line 34

def in_progress_for?(user)
  accessible_for?(user) && started?(user)
end

#limited_for?(exercise) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'app/models/exam.rb', line 142

def limited_for?(exercise)
  max_attempts_for(exercise).present?
end

#process_users(users) ⇒ Object



99
100
101
102
# File 'app/models/exam.rb', line 99

def process_users(users)
  users.map { |user| authorize! user }
  clean_authorizations users
end

#real_end_time(user) ⇒ Object



87
88
89
90
91
92
93
# File 'app/models/exam.rb', line 87

def real_end_time(user)
  if duration.present? && started?(user)
    [started_at(user) + duration.minutes, end_time].min
  else
    end_time
  end
end

#reindex_usages!Object



108
109
110
# File 'app/models/exam.rb', line 108

def reindex_usages!
  index_usage! organization
end

#resettable?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'app/models/exam.rb', line 146

def resettable?
  false
end

#start!(user) ⇒ Object



75
76
77
78
79
80
81
# File 'app/models/exam.rb', line 75

def start!(user)
  return if user.teacher_here?

  authorization = authorization_for(user)
  raise Mumuki::Domain::ForbiddenError unless authorization
  authorization.start!
end

#started?(user) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'app/models/exam.rb', line 83

def started?(user)
  authorization_for(user).try(:started?)
end

#started_at(user) ⇒ Object



95
96
97
# File 'app/models/exam.rb', line 95

def started_at(user)
  authorization_for(user).started_at
end

#timed?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'app/models/exam.rb', line 51

def timed?
  duration.present?
end

#used_in?(organization) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
# File 'app/models/exam.rb', line 18

def used_in?(organization)
  organization == self.organization
end

#validate_accessible_for!(user) ⇒ Object



38
39
40
41
42
43
44
45
# File 'app/models/exam.rb', line 38

def validate_accessible_for!(user)
  if user.present?
    raise Mumuki::Domain::ForbiddenError unless authorized?(user)
    raise Mumuki::Domain::GoneError unless enabled_for?(user)
  else
    raise Mumuki::Domain::UnauthorizedError
  end
end