class Exercise < ApplicationRecord belongs_to :course, counter_cache: true belongs_to :exercise_bank, optional: true belongs_to :user has_many :exercise_users, -> { where("is_delete = 0") }, :dependent => :delete_all has_many :score_exercise_users, -> { where("is_delete = 0 and commit_status != 0").order("score desc") }, class_name: "ExerciseUser" has_many :exercise_questions, :dependent => :delete_all has_many :exercise_group_settings, :dependent => :delete_all has_many :tidings, as: :container has_many :course_acts, class_name: 'CourseActivity', as: :course_act, :dependent => :delete_all scope :is_exercise_published, -> { where("exercise_status > ? ",1)} scope :unified_setting, -> { where("unified_setting = ?",true) } scope :exercise_by_ids, lambda { |ids| where(id: ids) unless ids.blank? } scope :exercise_by_status, lambda { |s| where(exercise_status: s) unless s.blank? } scope :exercise_search, lambda { |keywords| where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?} validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } after_create :create_exercise_list def create_exercise_list str = "" # TODO: 一次性为所有学生创建数据是否存在问题? self.course.students.find_each do |student| str += "," if str != "" str += "(#{student.user_id}, #{self.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if str != "" sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str ActiveRecord::Base.connection.execute sql end end #获取学生视角的试卷用户 def get_stu_exercise_users if unified_setting #试卷统一设置 exercise_users else ex_group_setting_ids = exercise_group_settings.exercise_group_published.pluck(:course_group_id) course_user_ids = course.students.where(course_group_id:ex_group_setting_ids).pluck(:user_id) exercise_users.where(user_id:course_user_ids) end end def get_exercise_end_time(user_id) if unified_setting self&.end_time else user_course_group = course.course_members.find_by(user_id: user_id)&.course_group_id exercise_group_settings.find_by(course_group_id:user_course_group)&.end_time end end #统一设置,为当前老师有权限的分班学生,分班设置,也为当前老师有权限的分班的学生 def all_exercise_users(user_id) ex_users = self.exercise_users group_ids = common_published_ids(user_id) if group_ids.present? ex_users = ex_users.where(user_id: course.students.where(course_group_id: group_ids).pluck(:user_id)) end ex_users end #当前用户已发布的班级id和试卷分组已发布的班级id的交集 def common_published_ids(user_id) current_user_groups = course.teacher_course_ids(user_id) if unified_setting un_group_ids = (course.none_group_count > 0) ? [0] : [] published_group_ids = (current_user_groups + un_group_ids).uniq #统一设置时,为当前用户的分班id及未分班 else ex_group_setting = exercise_group_settings.pluck("course_group_id").uniq common_all_ids = ex_group_setting & current_user_groups #当前用户有权限的已发布的分班id #非统一设置时,为当前用户有权限的且已发布分班的id published_group_ids = common_all_ids.uniq end published_group_ids end #判断用户是否属于试卷分班的学生中 def check_user_in_course(user_id,user_identity) ex_group_settings = exercise_group_settings.pluck(:course_group_id) member = course.course_members.course_find_by_ids("user_id",user_id) member_group_id = member.pluck(:course_group_id).uniq ((member_group_id & ex_group_settings).size > 0 || user_identity < Course::STUDENT) ? true : false end #判断是否为分班,如果分班,试卷的截止时间为当前分班时间,否则为试卷的截止时间 def get_exercise_status(user_id) user_group = course.course_members.find_by(user_id: user_id) if user_group.present? && user_group.role == "STUDENT" #当为学生的时候,需根据分班来判断试卷状态 ex_time = get_exercise_times(user_id,false) pb_time = ex_time[:publish_time] ed_time = ex_time[:end_time] if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now status = 2 elsif ed_time.present? && ed_time <= Time.now status = 3 else status = 1 end else status = exercise_status #当为老师的时候,则为试卷的总状态 end status end #获取试卷的发布时间和截止时间。teacher 为boolean,当为true时,表示的是当前为老师 def get_exercise_times(user_id,teacher) if unified_setting || teacher #当试卷为统一设置或当前为老师的时候 pb_time = publish_time en_time = end_time if en_time.present? && (en_time <= Time.now) && (exercise_status != 3) update_column("exercise_status",3) end else ex_group_setting = exercise_group_settings user_group = course.students.course_find_by_ids("user_id",user_id) if user_group.exists? user_group_id = user_group.first.course_group_id user_ex_group_setting = ex_group_setting.find_in_exercise_group("course_group_id",user_group_id) pb_time = user_ex_group_setting.exists? ? user_ex_group_setting.first.publish_time : nil en_time = user_ex_group_setting.exists? ? user_ex_group_setting.first.end_time : nil else pb_time = nil en_time = nil end end { "publish_time":pb_time, "end_time":en_time } end #判断当前用户的答题状态 def check_user_answer_status(user) ex_answer_user = exercise_users.find_by(user_id: user.id) user_ex_status = get_exercise_status(user.id) user_status = 2 if ex_answer_user.exists? && (ex_answer_user.start_at.exists? || ex_answer_user.end_at.exists?) #学生有过答题的,或者立即截止,但学生未做试卷的 user_status = ex_answer_user.commit_status end if ex_answer_user.exists? && ex_answer_user.start_at.blank? && user_ex_status == 3 user_status = 4 end user_status end end