Reputation: 45
I've started off with a single Rails application. Very simple, largely read-only, front end for a line of business application (using view backed to retrieve data) - with a few standard tables to augment the views.
I now have a need to use the same set of data in a new application (the 2 applications, whilst sharing the same data, work differently enough its not trivial to try and merge them into the same application).
I figured it would be easiest to split the models I can reuse into their own engine and have the 2 applications share the database.
Adding an API and having both applications query that is an option, but in practice I'm not sure I can provide an API that will satisfy both applications properly, as they use the data in different ways.
On that basis I figured if I gave each application a table prefix, or use different schemas to namespace them - that way each application has it's own distinct tables for stuff they don't share, but I can easily reuse the existing views without having to duplicate them.
Both options seems to work great, except I forgot about migrations for the common views and data.
So the only things I can think of are:
Since the 2 applications are kinda tightly coupled anyway, I have no migrations in my common data engine at all - any changes to the views/tables will be dealt with by the "first" application. This seems a bit nasty, since the models are now contained in a separate engine. I dislike the idea of having migrations in the engine and then copying them into one or the other, since that's basically the same thing.
I use pivotal labs advice, but add some code to detect if it's in the "first" application, and only apply to that. If I fail to do that I end up with both applications including the engine migrations, which results in both applications trying to run the same migrations, and causing nothing but pain.
I actually split off the common data into it's own database. So application #1 uses db #1, application #2 uses db #2, and the common data is housed in db #3 and accessible by both applications. With a bit of faffing, I'm guessing I can end up with 3 dbs, 3 schema_migrations, and I can just blindly leave my migrations in the engine, and include them in both applications as per pivotal labs - my plan is to do something like this to make all this work, and have the common models setup to connect to their own DB, rather than the application DB
Stick with 1 db and multiple schemas, and somehow setup a task to run the engine migrations only, using an account locked down to it's own schema only - that way it creates it's own schema_migrations.
I kinda feel paralyzed as I'm not sure what is the least shitty option. 3 or 4 feels "best", but not great.
Upvotes: 1
Views: 335
Reputation: 45
As an update to this, due to how tightly coupled the 2 applications are, and other needs that came up yesterday, I've ended up pulling the migrations out of both and using active_record_migrations to manage and orchestrate the migrations for both applications.
Effectively I could've done the same by having a dummy or master application, however this feels somewhat cleaner.
However, this comes at the expense of being able to use models effectively in the migrations. For my use case this doesn't matter at all.
Upvotes: 0
Reputation: 8212
I think 3 is the best option. However, I'd expose the common db #3 data via an api. That is, have an application that is used to manage the shared data (HTML admin interface, and json feeds for the other apps to connect on).
Keep the shared data app really simple. Just CRUD actions on the data. So the other two apps will grab the data from the shared data app, manipulate to match local requirements, and then display it; or allow input - manipulate the input to match the shared structure, and then persist via the shared data app's API update/create actions.
Upvotes: 1