Skip to content

Commit

Permalink
NEW Add migration task from gorriecoe/silverstripe-link (#253)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Apr 1, 2024
1 parent bc1f7c9 commit 495dc35
Show file tree
Hide file tree
Showing 10 changed files with 2,374 additions and 472 deletions.
117 changes: 62 additions & 55 deletions docs/en/09_migrating/00_upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,74 @@ This guide will help you update to the latest version of `silverstripe/linkfield
## Setup

1. Take a backup of your database
1. Update your composer dependency for `silverstripe/linkfield` to `^4`
> [!TIP]
> We strongly recommend taking a backup of your database before doing anything else.
> This will ensure you have a known state to revert to in case anything goes wrong.
```bash
composer require silverstripe/linkfield:^4
### Update your dependencies

Update your composer dependency for `silverstripe/linkfield` to `^4`

```bash
composer require silverstripe/linkfield:^4
```

### Configure the migration task

1. Enable the task:

```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
is_enabled: true
```
1. Declare any `has_many` relations that need to be migrated:

```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
# ...
has_many_links_data:
# The class where the has_many relation is declared
App\Model\MyClass:
# The name of the has_many relation
LinkListOne:
# The class where the old has_one relation was declared
# This will be either be Link or a Link subclass (not an extension applied to a Link class)
linkClass: 'SilverStripe\LinkField\Models\Link'
# The old name of the has_one relation on Link or a Link subclass
hasOne: 'MyOwner'
```

1. Update relations
- If the `has_one` relation for the record which owns the links (e.g. `Page`) has a corresponding `belongs_to` relation on the `Link` model (either added via an extension or YAML configuration), remove the `belongs_to` relation from the `Link` model.
- For any `has_many` relations to links on the record that owns the links (e.g. `Page`), update the dot notation to point to the `Owner` relation:
1. Declare any classes that may have `has_one` relations to `Link`, but which do not *own* the link. Classes declared here will include any subclasses.
For example if a custom link has a `has_many` relation to some class which does not own the link, declare that class here so it is not incorrectly identified as the owner of the link:

```diff
private static array $has_many = [
- 'LinkListOne' => Link::class . '.FirstHasOne',
+ 'LinkListOne' => Link::class . '.Owner',
- 'LinkListTwo' => Link::class . '.SecondHasOne',
+ 'LinkListTwo' => Link::class . '.Owner',
];
```
```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
# ...
classes_that_are_not_link_owners:
- App\Model\SomeClass
```

### Update your codebase

- Remove the `has_one` relation on the relevant `Link` class which was storing the `has_many` relations.
- e.g. for the above, remove the `FirstHasOne` and `SecondHasOne` relations from the `Link` class. You may have applied these via an `Extension` class or via YAML configuration.
- If the models that have `has_one` or `has_many` relations to link don't already use `$owns` configuration for those relations, add that now. You may also want to set `$cascade_deletes` and `$cascade_duplicates` configuration. See [basic usage](../01_basic_usage.md) for more details.
1. If the `has_one` relation for the record which owns the links (e.g. `Page`) has a corresponding `belongs_to` relation on the `Link` model (either added via an extension or YAML configuration), remove the `belongs_to` relation from the `Link` model.
1. For any `has_many` relations to links on the record that owns the links (e.g. `Page`), update the dot notation to point to the `Owner` relation:

```diff
private static array $has_many = [
- 'LinkListOne' => Link::class . '.FirstHasOne',
+ 'LinkListOne' => Link::class . '.Owner',
- 'LinkListTwo' => Link::class . '.SecondHasOne',
+ 'LinkListTwo' => Link::class . '.Owner',
];
```

> [!WARNING]
> `many_many` relations to `Link` are not supported. If you have any `many_many` relations to links you will need to migrate these to `has_many` relations yourself.
1. Remove the `has_one` relation on the relevant `Link` class which was storing the `has_many` relations.
- e.g. for the above, remove the `FirstHasOne` and `SecondHasOne` relations from the `Link` class. You may have applied these via an `Extension` class or via YAML configuration.
1. If the models that have `has_one` or `has_many` relations to link don't already use `$owns` configuration for those relations, add that now. You may also want to set `$cascade_deletes` and `$cascade_duplicates` configuration. See [basic usage](../01_basic_usage.md) for more details.

> [!WARNING]
> `many_many` relations to `Link` are not supported. If you have any `many_many` relations to links you will need to migrate these to `has_many` relations yourself.

## Customising the migration

Expand All @@ -69,41 +111,6 @@ For databases that support transactions, the full data migration is performed wi
> We strongly recommend running this task in a local development environment before trying it in production.
> There may be edge cases that the migration task doesn't account for which need to be resolved.

1. Prepare the task
- Enable the task:
```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
is_enabled: true
```
- Declare any `has_many` relations that need to be migrated:
```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
# ...
has_many_links_data:
# The class where the has_many relation is declared
App\Model\MyClass:
# The name of the has_many relation
LinkListOne:
# The class where the old has_one relation was declared
# This will be either be Link or a Link subclass (not an extension applied to a Link class)
linkClass: 'SilverStripe\LinkField\Models\Link'
# The old name of the has_one relation on Link or a Link subclass
hasOne: 'MyOwner'
```
- Declare any classes that may have `has_one` relations to `Link`, but which do not *own* the link. Classes declared here will include any subclasses.
For example if a custom link has a `has_many` relation to some class which does not own the link, declare that class here so it is not incorrectly identified as the owner of the link:
```yml
SilverStripe\LinkField\Tasks\LinkFieldMigrationTask:
# ...
classes_that_are_not_link_owners:
- App\Model\SomeClass
```
1. Run dev/build and flush your cache (use the method you will be using the for next step - i.e. if you're running the task via the terminal, make sure to flush via the terminal)
- via the browser: `https://www.example.com/dev/build?flush=1`
- via a terminal: `sake dev/build flush=1`
Expand Down
Loading

0 comments on commit 495dc35

Please sign in to comment.