Как ссылаться на ранее созданный объект в цикле создания Rails / Ruby - PullRequest
0 голосов
/ 03 апреля 2019

Итак, у меня есть концепция Кампании, которая имеет время начала и окончания. Я создаю небольшую задачу по рейку, которую я буду использовать, чтобы «повторить» или «повторить» кампанию снова, снова и снова по заданному графику.

Это структура задачи rake и как может выглядеть пример команды rake:

$ rake repeatcampaigns:repeatcampaign[:campaign_id, :repeat_times, :repeat_interval]

$ rake repeatcampaigns:repeatcampaign[28,2,monthly]

В приведенном выше примере мы возьмем Кампанию с идентификатором 28 и повторим ее дважды, начиная с месяца (т.е. каждая новая кампания будет начинаться через 30 дней после окончания предыдущей).

Более подробный пример:

  • Кампания 1 начинается 2019-01-01 и заканчивается 2019-01-03 (продолжительность 2 дней)
  • Мы хотим повторить Кампанию 1 дважды и с недельным интервалом (+7 дни) Поэтому кампания 2 должна начаться через 7 дней после окончания Кампания 1 (2019-01-10) и имеет одинаковую продолжительность 2 дня и, таким образом, должно закончиться 2019-01-12
  • Кампания 3 должна начаться через 7 дней после конец Кампании 2 (2019-01-19) и имеет ту же продолжительность 2 дни и, следовательно, должны заканчиваться 2019-01-21.

Так что у меня все работает, кроме одной важной вещи - я не совсем понимаю, как работает цикл.

Мне нужно установить start_time и end_time для ПЕРВОЙ вновь созданной кампании на основе родительской кампании (как вы видите в коде ниже), но для каждой новой кампании в цикле она должна ссылаться на ранее создал новую кампанию из цикла.


desc 'Repeat campaigns'
  namespace :repeatcampaigns do
    desc 'Repeat and publish a campaign X number of times again'
    task :repeatcampaign, [:campaign_id, :repeat_times, :repeat_interval] => [:environment] do |_t, args|

      @parent_campaign = Campaign.find(args[:campaign_id])
      times_to_repeat = args[:repeat_times].to_i
      repeat_interval = args[:repeat_interval]

      @days_to_add_to_start_time = convert_interval_to_days_for_repeat(repeat_interval)

      # Create X new campaigns based on the schedule input
      times_to_repeat.times do |index|
        @start_time = @parent_campaign.end_time + @days_to_add_to_start_time.days
        @new_campaign = Campaign.create(
          :name => "Repeat of campaign #{index}",
          :start_time => @start_time, 
          :end_time => @start_time + @parent_campaign.duration_in_days.days
        )
      end

    end

    def convert_interval_to_days_for_repeat(repeat_interval)
      case repeat_interval
      when "daily"
        return 1
      when "weekly"
        return 7
      when "monthly"
        return 30
      end  
    end

  end

Как я уже сказал, код работает нормально и создает новые кампании, однако даты новых кампаний всегда основаны на родительской кампании, а не на ранее созданной кампании. Так что я знаю, что мне нужно как-то адаптировать этот цикл, но не знаю, с чего начать!

Хотелось бы получить руководство по этому вопросу! Заранее спасибо!

1 Ответ

2 голосов
/ 03 апреля 2019

Я думаю, вам просто нужно переназначить @parent_campaign после создания новой кампании, например:

...
@new_campaign = Campaign.create(
                  :name => "Repeat of campaign #{index}",
                  :start_time => @start_time, 
                  :end_time => @start_time + @parent_campaign.duration_in_days.days
                )
@parent_campaign = @new_campaign
...
...