Получить вращающегося пользователя для правила повторения ice_cube

#ruby-on-rails #ruby #ice-cube

#ruby-on-rails #ruby #ice-cube

Вопрос:

Например, у меня есть правило повторения ice_cube, которое происходит ежедневно. Целью этого правила является ежедневная ротация пользователей.

Например, если у меня 4 пользователя: Джон, Питер, Марк, Мэтью и правило ежедневного повторения. Я также использую отложенные задания для создания одного задания для запуска в 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(amp;: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
  

Ответ №1:

Вы автоматически увеличиваете значение приоритета пользователей, верно?

 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 раз, где я приземлюсь?

Я знаю, что Мэтью сегодня № 1, где он будет через 2 дня? #3.

Вот наши переменные:

  • x = количество дней в будущем, которое вы хотите предсказать
  • priority_array_size = количество возможных приоритетов (4 в этом примере) и равно schedule_user.size
  • current_priority = текущий приоритет schedule_user для schedule_user
  • приоритет = приоритет для schedule_user x дней в будущем

Уравнение для вычисления этого может быть:

приоритет = x.остаток (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