编辑#1
这就是我现在拥有的
<% if course.complete? %>
<%= link_to "Completed", course, class: "block text-lg w-full text-center text-white px-4 py-2 bg-green hover:bg-green-dark border-2 border-green-dark leading-none no-underline" %>
<% else %>
<%= link_to "View Modules", course, class: "block text-lg w-full text-center text-grey-dark hover:text-darker px-4 py-2 border-2 border-grey leading-none no-underline hover:border-2 hover:border-grey-dark" %>
<% end %>
course_module.rb
class CourseModule < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
belongs_to :course
has_many :course_exercises
validates :title, :course_id, presence: true
scope :completed, -> { 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
名称匹配,所以在那里没有问题,但是,我将如何调用模型方法?
原始问题
当前,我有课程,并且在课程中,我的模块都有完整的列,它们都是布尔值。目前,学生可以通过单击类似的勾号来完成模块
我有像这样的课程数据库
以及类似的模块表
但是我希望该功能能够正常工作,因此当最后一个模块标记为已完成时,课程本身会在数据库中标记为已完成,当前在我拥有的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
这适用于模块,但是如果最后一个任务已标记为完成,我想将课程标记为已完成。
答案 0 :(得分:3)
您可以在控制器中或模型中的after_save
中执行此操作,但是它看起来像这样:
course = course_module.course
course.update(complete: true) if course.course_modules.all?(&:complete?)
如果名称与您的架构不太匹配,可能需要进行少量修改。
答案 1 :(得分:2)
似乎该逻辑将属于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
在完成后可能变得不完整,那么您将不得不在此处更改一些逻辑。
答案 2 :(得分:0)
因此,此问题的答案是@elliotcm和@engineersmnky的答案的组合。
最终答案是这样:
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
的每次保存时运行回调。并且即使它已经标记为完成,也会每次(如果其所有课程模块都已完成)更新course.complete
。通过稍微修改回调来避免所有这些事情:
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
也需要标记为未完成。