-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathlessons_controller.rb
More file actions
131 lines (108 loc) · 3.86 KB
/
lessons_controller.rb
File metadata and controls
131 lines (108 loc) · 3.86 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
# frozen_string_literal: true
module Api
class LessonsController < ApiController
include RemixSelection
before_action :authorize_user, except: %i[index show]
before_action :verify_school_class_belongs_to_school, only: :create
load_and_authorize_resource :lesson
def index
accessible_lessons = filtered_lessons_scope
.accessible_by(current_ability)
.includes(project: :remixes)
@lessons_with_users = accessible_lessons.with_users
if current_user&.school_teacher?(school) || current_user&.school_owner?(school)
render :teacher_index, formats: [:json], status: :ok
else
remixes = user_remixes(accessible_lessons)
@lessons_with_users_and_remixes = @lessons_with_users.zip(remixes)
render :student_index, formats: [:json], status: :ok
end
end
def show
@lesson_with_user = @lesson.with_user
render :show, formats: [:json], status: :ok
end
def create
result = Lesson::Create.call(lesson_params:)
if result.success?
@lesson_with_user = result[:lesson].with_user
render :show, formats: [:json], status: :created
else
render json: { error: result[:error] }, status: :unprocessable_content
end
end
def create_copy
result = Lesson::CreateCopy.call(lesson: @lesson, lesson_params:)
if result.success?
@lesson_with_user = result[:lesson].with_user
render :show, formats: [:json], status: :created
else
render json: { error: result[:error] }, status: :unprocessable_content
end
end
def update
# TODO: Consider removing user_id from the lesson_params for update so users can update other users' lessons without changing ownership
# OR consider dropping user_id on lessons and using teacher id/ids on the class instead
result = Lesson::Update.call(lesson: @lesson, lesson_params:)
if result.success?
@lesson_with_user = result[:lesson].with_user
render :show, formats: [:json], status: :ok
else
render json: { error: result[:error] }, status: :unprocessable_content
end
end
def destroy
@lesson.destroy!
head :no_content
end
private
def filtered_lessons_scope
scope = params[:school_class_id] ? Lesson.where(school_class_id: params[:school_class_id]) : Lesson.all
scope = scope.joins(:project).where(projects: { identifier: params[:project_identifier] }) if params[:project_identifier].present?
scope.order(created_at: :asc)
end
def verify_school_class_belongs_to_school
return if base_params[:school_class_id].blank?
return if school&.classes&.pluck(:id)&.include?(base_params[:school_class_id])
raise ParameterError, 'school_class_id does not correspond to school_id'
end
def user_remixes(lessons)
lessons.map { |lesson| user_remix(lesson) }
end
def user_remix(lesson)
return nil unless lesson&.project&.remixes&.any?
remix_for_user(
lesson.project,
current_user,
include_feedback: current_user&.school_student?(school)
)
end
def lesson_params
base_params.merge(user_id: current_user.id)
end
def base_params
params.fetch(:lesson, {}).permit(
:school_id,
:school_class_id,
:name,
:description,
:visibility,
:due_date,
{
project_attributes: [
:name,
:project_type,
:locale,
{ components: %i[id name extension content index default] }
]
}
)
end
def school_owner?
school && current_user.school_owner?(school)
end
def school
@school ||= @lesson&.school || School.find_by(id: base_params[:school_id]) || SchoolClass.find_by(id: params[:school_class_id])&.school
end
end
end