-
Notifications
You must be signed in to change notification settings - Fork 7
Command to migrate legacy campaigns from Ashes -> Rogue #783
Conversation
One note - there is only one campaign that I found in the export that has |
// Create the campaign if there isn't one already | ||
if (! $existing_campaign) { | ||
// If there is no campaign_id, set the campaign_run_id to the id. | ||
if (is_null($legacy_campaign['campaign_id'])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that in the csv runs will not have the campaign_id
column populated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@katiecrane great q! It will have the campaign_id
column! However, after running the query, some campaigns didn't have this populated so wanted to account for these edge cases. Happy to share the CSV I'm working with too if that is helpful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OH or does it mean that only CURRENT runs will have the `campaign_id populated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee hmmmm does that mean that there are runs not attached to any campaign? I think seeing the CSV would help!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee ah okay I see, the first 7 rows are the ones with null
. Are these actual campaigns? Seems like one of them is the DS app and 5 of them are in Spanish?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, these look like placeholder campaigns. I think it's safe to add them with the script, and we can delete later.
if (is_null($legacy_campaign['campaign_id'])) { | ||
$campaign = $this->createCampaign($legacy_campaign['run_id'], $legacy_campaign); | ||
// If the campaign_id does not equal the next record's campaign_id or the previous record's campaign id, this is either the latest run or there is only one campaign run, so keep the original campaign_id as the id in Rogue. | ||
} else if ($legacy_campaigns_csv->fetchOne($iterator) && $legacy_campaign['campaign_id'] != $legacy_campaigns_csv->fetchOne($iterator)['campaign_id'] && $legacy_campaign['campaign_id'] != $legacy_campaigns_csv->fetchOne($iterator - 1)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be easier to look at if this logic was extracted into a shouldUseCampaignId
function? But I guess it might still all end up on one line. What do you think @chloealee ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this line is pretty intimidating. I'm not super concerned since this is a one-time script and we can easily check our work, but could be nice to clean up for readability.
public function testImportingLegacyCampaigns() | ||
{ | ||
// Run the legacy campaign import command | ||
$this->artisan('rogue:ashescampaignsimport', ['path' => 'tests/Console/example-legacy-campaigns.csv']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yesssss thank you for making tests for this!! 🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1! So helpful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few little thoughts, but I'm good to merge this as long as it's thoroughly tested!
{ | ||
// Make a local copy of the CSV | ||
$path = $this->argument('path'); | ||
info('rogue:legacycampaignimport: Loading in csv from ' . $path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just print these to standard output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DFurnes not sure what you mean by that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee that would be doing $this->line('rogue:legacycampaignimport: Loading in csv from ' . $path)
. It'll print out in your terminal locally and when running on a one-off dyno in Heroku, it will print to the logs for that dyno (which is something we figured out semi-recently!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh!! this is so much better then taking up room in the Papertrail! updated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it will still log to PaperTrail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooooo what are the benefits of logging this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee I was trying to remember that too! Looks like it's a memory thing and using info()
a bunch of times can cause a memory leak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah got it, thanks for explaining, @katiecrane !
} | ||
|
||
// See if the campaign exists | ||
$existing_campaign = Campaign::where('id', $legacy_campaign['campaign_id'])->orWhere('id', $legacy_campaign['run_id'])->first(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this always find the "current run" that has the campaign ID? Say, if we create a campaign 6170
for campaign_id:6170,run_id:8
, and then want to create a new campaign 7
for campaign_id:6170,run_id:7
, I think this would just skip that second one, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or does this work since we know campaigns are sorted in reverse order of old runs → current?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DFurnes great q! Yes, this should work because the way we write the query and export the results to a CSV from Ashes, it'll always be reverse order of old runs -> current like you said.
Here's an example!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, sounds good! 🤞
Yes, let's do that! |
} else if ($legacy_campaigns_csv->fetchOne($iterator) && | ||
$legacy_campaign['campaign_id'] != $legacy_campaigns_csv->fetchOne($iterator)['campaign_id'] && | ||
$legacy_campaign['campaign_id'] != $legacy_campaigns_csv->fetchOne($iterator - 1)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@katiecrane @DFurnes I agree this is a little hard to read! Since it is just for this script, I'm not sure if it would make it that much easier to read if broken into a separate helper function but I played with the formatting to see if this would make it easier to read - lmk what you think!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee I love this! makes it much more readable!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok great, thanks @katiecrane !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, much nicer! 👁
…g/editing/viewing a campaign
} | ||
|
||
$this->line('rogue:legacycampaignimport: Created campaign ' . $campaign->internal_title); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@katiecrane @DFurnes I changed this log message to log the campaign title instead of the ID because I feel like that is more readable - lmk if you don't think this is a good idea though!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chloealee whatever you think will be the most useful works for me 😄
app/Models/Campaign.php
Outdated
@@ -21,7 +21,7 @@ class Campaign extends Model | |||
* | |||
* @var array | |||
*/ | |||
protected $fillable = ['internal_title', 'cause', 'start_date', 'end_date']; | |||
protected $fillable = ['id','internal_title', 'cause', 'secondary_causes', 'campaign_run_id', 'impact_doc', 'start_date', 'end_date', 'created_at', 'updated_at']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove id
, created_at
, and updated_at
from the fillable array & use Campaign::forceCreate
in the script (since we don't want these to be mass-assignable elsewhere).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool i didn't know about forceCreate
! Much better solution!
Schema::table('campaigns', function (Blueprint $table) { | ||
$table->string('secondary_causes')->index()->after('cause')->nullable()->comment('Secondary causes associated with legacy campaigns'); | ||
$table->integer('campaign_run_id')->index()->after('secondary_causes')->nullable()->comment('Campaign Run Id to reference when we run script to update signup and post ids after legacy campaign migration. This column can be deleted once migration and update script are complete.'); | ||
$table->string('impact_doc')->index()->after('campaign_run_id')->nullable()->comment('URL to proof of impact doc.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need an index on the impact_doc
column since it won't be queried against.
@@ -64,6 +64,7 @@ public function store(Request $request) | |||
$this->validate($request, [ | |||
'internal_title' => 'required|string|unique:campaigns', | |||
'cause' => 'required|string', | |||
'impact_doc' => 'required|string', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the url
validator to enforce that this is a URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great call!
@@ -126,6 +127,7 @@ public function update(Request $request, Campaign $campaign) | |||
$this->validate($request, [ | |||
'internal_title' => 'string', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing the unique:campaigns
validation rule that we use when creating a new campaign.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can include it here by specifying a campaign ID to ignore for the uniqueness check, e.g:
'internal_title' => [Rule::unique('campaigns')->ignore($campaign->id)],
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very cool, thanks @DFurnes !
7a82353
to
1e6e0de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me!
What's this PR do?
campaigns
table:secondary_causes
columncampaign_run_Id
columninternal_doc
columnHow should this be reviewed?
Relevant tickets
Fixes task 3 in this Pivotal Card.
How to deploy
https://github.com/DoSomething/rogue/blob/master/docs/development/deployments.md