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, name_model_as, numbered, #save, #save_and_notify!, #save_and_notify_changes!, #update_and_notify!, update_or_create!

Class Method Details

.import_from_json!(json) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/models/exam.rb', line 99

def self.import_from_json!(json)
  json.except!(:social_ids, :sender)
  organization = Organization.find_by!(name: json.delete(:organization))
  organization.switch!
  exam_data = parse_json json
  remove_previous_version exam_data[:eid], exam_data[:guide_id]
  users = exam_data.delete(:users)
  exam = where(classroom_id: exam_data.delete(:eid)).update_or_create! exam_data
  exam.process_users users
  exam.index_usage! organization
  exam
end

.parse_json(exam_json) ⇒ Object



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

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

.remove_previous_version(eid, guide_id) ⇒ Object



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

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)


42
43
44
# File 'app/models/exam.rb', line 42

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

#authorization_for(user) ⇒ Object



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

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

#authorizations_for(users) ⇒ Object



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

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

#authorize!(user) ⇒ Object



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

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

#authorized?(user) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#clean_authorizations(users) ⇒ Object



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

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

#enabled?Boolean

Returns:

  • (Boolean)


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

def enabled?
  enabled_range.cover? DateTime.now
end

#enabled_for?(user) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#enabled_rangeObject



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

def enabled_range
  start_time..end_time
end

#enabled_range_for(user) ⇒ Object



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

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

#process_users(users) ⇒ Object



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

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

#real_end_time(user) ⇒ Object



78
79
80
81
82
83
84
# File 'app/models/exam.rb', line 78

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

#start!(user) ⇒ Object



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

def start!(user)
  authorization_for(user).start! unless user.teacher_here?
end

#started?(user) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'app/models/exam.rb', line 74

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

#started_at(user) ⇒ Object



86
87
88
# File 'app/models/exam.rb', line 86

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

#timed?Boolean

Returns:

  • (Boolean)


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

def timed?
  duration.present?
end

#used_in?(organization) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#validate_accessible_for!(user) ⇒ Object



33
34
35
36
37
38
39
40
# File 'app/models/exam.rb', line 33

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