Using a single master Repo for library where library contains it's own migrations (or alternatively how to test in this situation)

Hello

I’ve got the following setup and run into some problems when trying to test this:

So I’ve got a library “accounts” where I’ve got all my user/group/permission logic as well as the necessary migrations to create the tables, which is shared by some other actual apps. Currently this library uses it’s own Repo.

Next I’ve got a phoenix app that uses the “accounts” library (lets call it “master”), and more specifically the permission tables from that library. This app also has it’s own Repo, but the config for this Master.Repo and Accounts.Repo is shared, so in effect they both use the same DB.

The problem I’ve run into is when I’m trying to test this setup. I’m setting up my fixtures for the Master.Repo, including required users etc. However when creating a resource in the tests for the master app, that will call into the accounts app, which will try to grant some permissions on that resource. The last part of that operation will then fail, because using the sandbox mode of ecto the fixtures will only exist in the Master.Repo, but not in the Accounts.Repo, which is used by the “accounts” library.

Now I’ve got the following question: Is there either

a) Some way to get ecto to use the same sandbox for multiple repos? In that case I could simply keep this structure

or b) can I somehow configure the “accounts” library to use the repo from the “master” app, while keeping the migrations in the “accounts” library and not forcing the “master” app to write specific migrations?

Thanks already and have a good day

1 Like

In my opinion the requirement of keeping migrations strictly in “accounts” is a bad idea. Provide any user of your library (a.k.a. “master”) with a quick way to integrate your libraries migration needs into their own migrations and use the repo provided by them in your library. This allows “master” to be fully in charge of it’s db schema without any surprises.

3 Likes

Thanks @LostKobrakai, that gave me the right idea. For anyone stumbling upon the same question and looking for an answer:

I’ve now setup the “accounts” library as described here Setting Up Testing for Library and use a config setting like this to set the repo for the “accounts” lib:

config :accounts, repo: Master.Repo

I then create the migrations this way:

MIX_ENV=test mix ecto.gen.migration xxx

And finally I’ve created a simple mix task that copies those migrations into the priv/repo/migrations folder of the “master” app, which is aliased to mix deps.get and mix deps.update, i.e.:

in mix.exs:

def project do
    [
      ....
      aliases: aliases()
    ]
end

defp aliases do
    [
      "deps.update": ["deps.update", "migrations.merge"],
      "deps.get": ["deps.get", "migrations.merge"]
    ]
end