如果所有子模块都标记为完整导轨5

时间:2018-08-22 15:02:09

标签: ruby ruby-on-rails-5

编辑#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

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

原始问题

当前,我有课程,并且在课程中,我的模块都有完整的列,它们都是布尔值。目前,学生可以通过单击类似的勾号来完成模块

image

我有像这样的课程数据库

course

以及类似的模块表

modules

但是我希望该功能能够正常工作,因此当最后一个模块标记为已完成时,课程本身会在数据库中标记为已完成,当前在我拥有的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

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

3 个答案:

答案 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也需要标记为未完成。