Hello!
At my company, we are building an app that will manage the database of our multiples tenants.
This app has its own ROM container for its own database, and we are building a dynamic container resolver for the part that will manage a tenant database.
We store the container inside a simple relation
module Infrastructure
module Relations
class EnvironementConnections < ROM::Relation[:memory]
gateway :memory
schema(:environement_containers) do
attribute :environement_id, Types::String.meta(primary_key: true)
attribute :container, Types.Instance(ROM::Container)
end
end
end
end
Above that, I am building a middleware for injecting the dynamic container
module Application
module Middlewares
class EnvironementResolver
include Dry::Effects::Handler.Resolve
include Dry::Monads[:maybe]
def initialize(app, container_resolver:)
@app = app
@container_resolver = container_resolver
end
def call(env)
acquire_connection = @container_resolver.for_environement(env['HTTP_MEMORY_ENVIRONEMENT'])
case acquire_connection
in Some(connection)
provide(container: connection.container) { @app.call(env) }
in None()
@app.call(env)
end
end
end
end
end
And then, when calling the repository I want it to be dynamically injected
module MemoryInfrastructure
module Repositories
class UserRepository < ROM::Repository[:users]
include Dry::Effects.Resolve(:container)
def all
users.limit(10).to_a
end
end
end
end
The problem is that it didn’t work because ROM::Repository
overwrite the new
method.
How can I work around that?
I could call manually the class from the controller MemoryInfrastructure::Repositories::UserRepository.new(container).all
but I lost the advantage of dynamic injection.
Any idea?