Functionality extraction - lessons learned
I’m very close to releasing the first version of the plugin, so I’ve decided to share how it went.
In general this was very easy to do, as the trends are not tied up to other funcionalities. But there still were some difficulties I’ve faced during working on this and I’d like to share
Premisses I wanted to achieve during the extraction:
- Make the transition as smooth as possible.
- The code to be extracted should work for at least one more version, whilst the plugin can be installed and tested with this version.
- The plugin can be installed and removed easily and the old code that is in core should be still working.
I’ve decided to move the plugin to
isolated_namespace for two main reasons.
- I believe it’s a good practice, as the plugins are guaranteed not to collide with their routes and classes.
- It’s much easier to notice we’ve missed something that should’ve been moved and is still used from the core code.
The models are now in an isolated namespace, so it’s necessary to adjust the STI and class references. I needed to move the associations to the right classes and add a migration that will adjust the STI on existing records.
Routes from core can live alongside the routes from plugin, thanks to the isolated namespaces.
Only the menu items have to be adjusted to point to the plugin routes and we are all set.
Migrations are a bit tricky, as Rails won’t allow us to have two same migrations alongside each other, I’ve decided to add a new migration path that would be kept only as an extraction point and if we decide to keep the migrations as they are. This migration path is only added if the version of foreman is higher than version, that is planned not to include the extracted code.
Best case scenario we will create new migrations, that will rename or create the namespaced tables and thus finish the migration to the new
Settings turn out to be the hardest, as it’s almost impossible to adjust the existing setting category. I’m currently trying to improve the situation, so I’m not going to write more here. Please follow Setting in memory, only changed values in database for details.
I’ve kept the same permissions as we had, so I only needed to adjust the routes and resources the permissions are related to. For that in memory I needed to remove the old ones and add the same ones with new routes and in the database migrate the resources for those permissions. It could definitely be easier for plugins to adjust permissions, but I’ve decided not to touch this as it can be done without too much pain even now.