0

例如,我有一个 ice_cube 重复规则,它每天都会发生。此规则的目标是每天轮换用户。

例如,如果我有 4 个用户:John、Peter、Mark、Matthew 和每日重复规则。我还使用延迟作业来创建单个作业以在 next_occurence 上运行,这将轮换 schedule_users 表中的用户(通过更改优先级值)。我一次只创建一个作业,例如,当执行第一次轮换时,将为下一次创建一个新作业。

我想查看哪些用户被安排在特定的一天。我将如何展望未来 3、5、7 等或未来任意天数的用户。

class Schedule < ApplicationRecord    
  belongs_to :project
  belongs_to :user

  has_many :schedule_users, -> { order priority: :desc }, dependent: :destroy
  has_many :users, through: :schedule_users

  enum frequency: { daily: 0, weekly: 1, biweekly: 2, monthly: 3 }

  validates_presence_of :name, :start, :frequency, :project
    
  def next_occurrence
    ice_cube_schedule.next_occurrence.start_time
  end

  def jobs
    Delayed::Job.where('handler LIKE ?', "%Schedule/#{id}\%")
  end

  def on_call_user
    schedule_users.max_by(&:priority).user if users.present?
  end

  def priority(user)
    schedule_users.where(user: user).first.try(:priority)
  end

  def ice_cube_schedule
    schedule = IceCube::Schedule.new(start, end_time: self.end)

    case frequency
    when 'daily'
      schedule.add_recurrence_rule IceCube::Rule.daily(1)
    when 'weekly'
      schedule.add_recurrence_rule IceCube::Rule.weekly(1)
    when 'biweekly'
      schedule.add_recurrence_rule IceCube::Rule.weekly(2)
    when 'monthly'
      schedule.add_recurrence_rule IceCube::Rule.monthly(1)
    end
    schedule
  end
end

class ScheduleUser < ApplicationRecord
  belongs_to :schedule
  belongs_to :user

  validates_presence_of :priority, :schedule, :user
end

class ReprioritizeScheduleUsersJob < ApplicationJob
  queue_as :default

  after_perform do |job|
    schedule = job.arguments.first
    ReprioritizeScheduleUsersJob.set(wait_until: schedule.next_occurrence).perform_later(schedule)
  end

  def perform(schedule)
    ActiveRecord::Base.transaction do
      schedule_users = schedule.schedule_users.reload
      num_users = schedule_users.count

      schedule.schedule_users.rotate.each_with_index do |schedule_user, index|
        schedule_user.update(priority: num_users - index)
      end
    end
  end
end
4

1 回答 1

0

您正在自动增加用户的优先级值,对吗?

schedule.schedule_users.rotate.each_with_index do |schedule_user, index|
  schedule_user.update(priority: num_users - index)
end

因此,如果有 4 个用户,您应该在第 1 天得到这样的结果:

ScheduleUser.all.pluck(:name, :priority)
[["Matthew", 1], ["Mark", 2], ["Luke", 3], ["John", 4]]

第 2 天:

ScheduleUser.all.pluck(:name, :priority)
[["Matthew", 2], ["Mark", 3], ["Luke", 4], ["John", 1]]

第 3 天:

ScheduleUser.all.pluck(:name, :priority)
[["Matthew", 3], ["Mark", 4], ["Luke", 1], ["John", 2]]

所以另一种思考问题的方法就像一个阵列轮。如果我在这个阵列中移动 X 次,我会降落在哪里?

我知道马修今天是第一名,两天后他会在哪里?#3。

这是我们的变量:

  • x = 您要预测的未来天数
  • priority_array_size = 可能的优先级数(本例中为 4),等于 schedule_user.size
  • current_priority = schedule_user 的当前优先级
  • priority = schedule_user x 未来几天的优先级

计算这个的方程可以是:

优先级 = x.remainder(priority_array_size) + current_priority

我建议这是一种方法ScheduleUser

class ScheduleUser < ApplicationRecord
  belongs_to :schedule
  belongs_to :user

  validates_presence_of :priority, :schedule, :user

  def priority_in_x_days(days_in_future)
    days_in_future.remainder(ScheduleUser.all.size) + priority
  end
end
于 2020-10-26T19:16:19.373 回答