对用户记录的追溯性更改(点协调)



我有三个模型:

    课程
  1. 用户
  2. CourseCompletion

除了标题和内容,每门课程也有一个积分值。当用户完成一门课程时,他们将获得该课程的积分值,该积分值将添加到他们的total_points中。courseccompletion简单地跟踪哪个用户完成了哪些课程(列user_id, course_idcompletion_date)。

此数据模型的一个缺点是,如果管理用户在用户完成课程后编辑课程的积分值,则不会更新该用户的积分。我需要一种追溯的方法。例如,如果用户完成一门课程并获得10分,然后管理员将该课程更改为20分,那么用户最终应该获得20分。我以前没有做过这种事情——最好的方法是什么?

我目前的计划是双重的。在第一部分中,我对Course和courseccompletion模型进行了更改:

  1. 在courseccompletion中添加一个points_earned列,记录用户完成该任务所获得的积分。
  2. 添加points_recently_changed列到Course。如果某个球场的积分在任何时候都有更新,那么将该球场的这一列设置为true。(见我的相关问题)

在第二部分中,脚本或任务(?)每天运行一次,并执行以下操作:

  1. 获取points_recently_changed = true的所有课程
  2. 查找这些课程的所有完成情况
  3. 计算航向差。积分和course_completion.points_earned
  4. 相应更新相应用户积分总数
  5. 改变方向。points_recently_updated返回false

这种方法有什么明显的问题吗,或者有"Rails方式"做这样的事情吗?

为什么不使用ActiveRecord:: calculation来获取所有相关课程的积分之和,并将其存储在列中。每当管理员更改课程点数时,更新该列。

您可以使用ActiveRecord::Dirty来跟踪点的变化

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

和计算点使用计算:

http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html

作为可能的解决方案:

class Course < ActiveRecord::Base
  before_save :update_user_points
  def update_user_points
    User.all.each {|user| user.update_points } if self.points_changed?
  end
end
class User < ActiveRecord::Base
  def update_points
    self.points = self.courses.sum(:points)
  end
end

建议:

我不喜欢在数据库中保存点,因为它是一个变量。我建议您在每次用户登录时进行计算,并将其作为带过期日期的缓存数。所以每天都要重新计算

我尝试了乔治的建议,但并不满意。我最终采用了类似的方法,即在登录过程中重新计算用户的分数。

User.rb

def recalculate_points
  new_course_points = self.course_completion_courses.sum(:worth)
  self.update_attribute(:points, self.course_completion_courses.sum(:worth))
  self.save
end

session_helper.rb

def sign_in(user)
  ...
  current_user.recalculate_points
end

点仍然存储在User表中—简单地缓存它们不起作用,因为我要做一些报告,需要将这些信息保存在数据库中。

最新更新