如果所有子模块都标记为完整导轨,则将课程标记为自动完成5

编辑#1

这就是我现在拥有的

     

course_module.rb

 class CourseModule  { where(complete: true) } after_save :course_completed private def course_completed course = course_module.course course.update(complete: true) if course.course_modules.all?(&:complete?) end end 

名称匹配,所以没有问题,但是,我将如何调用模型方法?

原始问题

目前,我有课程,在课程中我有模块都有完整的列,这是一个布尔,目前,学生可以通过点击勾选完成模块,所以

图片

我有这样的课程数据库

课程

和模块表一样

模块

但我希望function能够工作,所以当最后一个模块标记为完成时,课程本身在数据库中标记为完成,目前在course_modules_controller.rb我有

 def complete @course_module = CourseModule.friendly.find(params[:id]) @course_module.complete = true @course_module.save redirect_to courses_path, notice: 'Module completed, congratulations!' end 

这适用于模块,但如果最后一个任务已标记为完成,我想将课程标记为完成。

您可以在控制器中或模型中的after_save中执行此操作,但它看起来像这样:

 course = course_module.course course.update(complete: true) if course.course_modules.all?(&:complete?) 

如果名称与您的架构不完全匹配,可能需要进行少量编辑。

似乎这个逻辑属于CourseModule而不是Course因为CourseModule被完成是触发器。

类似的东西

 class Course < ApplicationRecord def complete! update_attribute(:complete,true) unless complete? end end class CourseModule < ApplicationRecord scope :completed, -> {where(complete: true) } after_save :update_course, if: :complete? private def update_course course.complete! if course.course_modules.count == course.course_modules.completed.count end end 

如果CourseModule在完成后可能变得不完整,那么你将不得不在这里更改一些逻辑。

所以这个问题的答案是@elliotcm和@ engineermnky的答案的组合。

最后的答案是这样的:

course.rb

 class Course < ApplicationRecord has_many :course_modules def complete! update_attribute(:complete, true) end end 

course_module.rb

 class CourseModule < ApplicationRecord belongs_to :course scope :completed, -> { where(complete: true) } scope :course_completed, -> { where(complete: true) } after_save :update_course, if: :complete? private def update_course course.complete! if course.course_modules.all?(&:complete?) end end 

谢谢你们的帮助!

更新

上面的解决方案将在course_module完成后的每次保存时运行回调。 并且每次都会更新课程(如果所有课程模块都已完成),即使它已经标记为已完成。 通过稍微修改回调来避免所有这些:

 class CourseModule < ApplicationRecord after_save :update_course, if: -> { complete_changed? && complete? } private def update_course return if course.complete? || CourseModule.where(course_id: course_id, complete: false).exists? course.complete! end end 

注意:您还需要处理course_module未完成的情况,因此,其相应的course也需要标记为不完整。