简体   繁体   中英

How to reference the previously created object in a create loop Rails/Ruby

So I have the concept of a Campaign which has a start_time and end_time. I am building a small rake task which I'll use to "repeat" or "recur" the campaign again, a set number of times again, on a set schedule.

This is the structure of the rake task and how an example rake command could look:

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

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

In this example above, we'd take the Campaign with an id 28 and repeat it twice, starting monthly (ie each new campaign would start 30 days after the previous one ended).

More detailed Example:

  • Campaign 1 starts on 2019-01-01 and ends on 2019-01-03 (duration of 2 days)
  • We want to repeat Campaign 1 twice and on a weekly interval (+7 days) Campaign 2 should therefore start 7 days after the end of Campaign 1 (2019-01-10) and has the same duration of 2 days and thus should end on 2019-01-12
  • Campaign 3 should then start 7 days after the end of Campaign 2 (2019-01-19) and has the same duration of 2 days and thus should end of 2019-01-21.

So I have everything working, except for one major thing - I cannot quite grasp how to work the loop.

I need to set the start_time and end_time for the FIRST newly created campaign based on the parent campaign (as you see in the code below), but for each new campaign in the loop, it should reference the previously created new campaign from the loop.


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

So as I say, the code runs fine and creates new campaigns, however the new campaigns dates are always based on the parent campaign, not the previously newly created campaign. So I know I need to adapt that loop somehow but no idea where to start!

Would love some guidance on this one! Thanks in advance!

I think you just need to reassign @parent_campaign after creating new campaign like this:

...
@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
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM