Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add create_from_project for lesson
  • Loading branch information
loiswells97 committed May 29, 2025
commit 8f0b20848e5f27e926718fb5fb3918642f93b4b8
18 changes: 17 additions & 1 deletion app/controllers/api/lessons_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Api
class LessonsController < ApiController
before_action :authorize_user, except: %i[index show]
before_action :verify_school_class_belongs_to_school, only: :create
load_and_authorize_resource :lesson
load_and_authorize_resource :lesson, except: [:create_from_project]

def index
archive_scope = params[:include_archived] == 'true' ? Lesson : Lesson.unarchived
Expand Down Expand Up @@ -41,6 +41,21 @@ def create_copy
end
end

def create_from_project
remix_origin = request.origin || request.referer

puts("lesson_params: #{lesson_params}")

result = Lesson::CreateFromProject.call(lesson_params: lesson_params, remix_origin:)

if result.success?
@lesson_with_user = result[:lesson].with_user
render :show, formats: [:json], status: :created
else
render json: { error: result[:error] }, status: :unprocessable_entity
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
Expand Down Expand Up @@ -86,6 +101,7 @@ def base_params
:description,
:visibility,
:due_date,
:project_identifier,
{
project_attributes: [
:name,
Expand Down
4 changes: 3 additions & 1 deletion app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def define_school_owner_abilities(school:)
can(%i[read create destroy], :school_owner)
can(%i[read create destroy], :school_teacher)
can(%i[read create create_batch update destroy], :school_student)
can(%i[create_from_project], Lesson)
can(%i[create create_copy], Lesson, school_id: school.id)
can(%i[read update destroy], Lesson, school_id: school.id, visibility: %w[teachers students public])
end
Expand All @@ -83,13 +84,14 @@ def define_school_teacher_abilities(user:, school:)
can(%i[create update destroy], Lesson) do |lesson|
school_teacher_can_manage_lesson?(user:, school:, lesson:)
end
can(%i[create_from_project], Lesson)
can(%i[read create_copy], Lesson, school_id: school.id, visibility: %w[teachers students])
can(%i[create], Project) do |project|
school_teacher_can_manage_project?(user:, school:, project:)
end
can(%i[read update show_context], Project, school_id: school.id, lesson: { visibility: %w[teachers students] })
can(%i[read], Project,
remixed_from_id: Project.where(school_id: school.id, remixed_from_id: nil, lesson_id: Lesson.where(school_class_id: ClassTeacher.where(teacher_id: user.id).select(:school_class_id))).pluck(:id))
remixed_from_id: Project.where(school_id: school.id, lesson_id: Lesson.where(school_class_id: ClassTeacher.where(teacher_id: user.id).select(:school_class_id))).pluck(:id))
end

def define_school_student_abilities(user:, school:)
Expand Down
7 changes: 7 additions & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Types
validate :project_with_instructions_must_belong_to_school
validate :project_with_school_id_has_school_project
validate :school_project_school_matches_project_school
validate :lesson_id_cannot_be_changed

default_scope -> { where.not(project_type: Types::SCRATCH) }

Expand Down Expand Up @@ -142,4 +143,10 @@ def school_project_school_matches_project_school

errors.add(:school_project, 'School project school_id must match project school_id')
end

def lesson_id_cannot_be_changed
return unless lesson_id_changed? && lesson_id_was.present?

errors.add(:lesson_id, 'cannot be changed once set')
end
end
2 changes: 1 addition & 1 deletion app/views/api/lessons/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ json.array!(@lessons_with_users) do |lesson, user|
:identifier,
:project_type
)
json.project.finished(lesson.project.finished) if lesson.project.remixed_from_id.present?
# json.project.finished(lesson.project.finished) if lesson.project.remixed_from_id.present?
end

json.user_name(user&.name)
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

resources :lessons, only: %i[index create show update destroy] do
post :copy, on: :member, to: 'lessons#create_copy'
post :create_from_project, on: :collection, to: 'lessons#create_from_project'
end

resources :teacher_invitations, param: :token, only: :show do
Expand Down
51 changes: 51 additions & 0 deletions lib/concepts/lesson/operations/create_from_project.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

class Lesson
class CreateFromProject
class << self
def call(lesson_params:, remix_origin:)
pp 'creating lesson from project!'
# ActiveRecord::Base.transaction do
response = OperationResponse.new
response[:lesson] = build_lesson_from_project(lesson_params, remix_origin)
response[:lesson].save!
response
rescue StandardError => e
Sentry.capture_exception(e)
pp(e)
errors = response[:lesson].errors.full_messages.join(',')
response[:error] = "Error creating remix of lesson: #{errors}"
response
# end
end

private

def build_lesson_from_project(lesson_params, remix_origin)
# original_project = Project.find_by(identifier: lesson_params[:project_identifier])
# lesson_copy = Lesson.new(name: original_project.name)
# filtered_params = lesson_params.except(:project_identifier)
# lesson_copy.assign_attributes(filtered_params)
# lesson_copy.project = build_project_remix(original_project, lesson_params, remix_origin)

# lesson_copy
project = Project.find_by(identifier: lesson_params[:project_identifier])
lesson = Lesson.new(
name: project.name)
lesson.assign_attributes(lesson_params.except(:project_identifier))
lesson.project = project
lesson
end

# def build_project_remix(original_project, lesson_params, remix_origin)
# response = Project::CreateRemix.call(
# params: {school_id: lesson_params[:school_id]},
# user_id: lesson_params[:user_id],
# original_project: original_project,
# remix_origin: remix_origin
# )
# response[:project]
# end
end
end
end