# Slices don't take db config from parent by default

**URL:** <https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072>\
**Category:** issues\
**Created:** [November 30, 2024, 6:49pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072 "2024-11-30T18:49:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![svoop](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/svoop/32/443_2.png) [@svoop](https://discourse.hanakai.org/u/svoop)\
**Post date:** [November 30, 2024, 6:49pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/1 "2024-11-30T18:49:52Z")

</div>

Hiya!

There’s either a bug in Hanami or an inconsistency in the guides on the subject of slices inheriting the db config from the parent. The guides claim this is the default and can be disabled in the slice config:

> **[V2.2: Configuration | Hanami Guides](https://guides.hanamirb.org/v2.2/database/configuration/#slice-configuration)**
>
> V2.2: Configuration | Hanami Guides

However, it appears to be the other way around, I have to explicitly set this config to `true` for the slice to inherit the db. Here’s a little demo app to illustrate:

> **[Commits · svoop/demo](https://github.com/svoop/demo/commits/main/)**
>
> Hanami 2.2 demo app for the db issue. Contribute to svoop/demo development by creating an account on GitHub.

In order to fix this: Can anyone tell whether the default in Hanami is wrong or whether it’s just a misinformation in the guides?

Cheers! -sven

---

<div class="post-metadata">

**Author:** ![timriley](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/timriley/32/621_2.png) [@timriley](https://discourse.hanakai.org/u/timriley)\
**Post date:** [December 1, 2024, 5:31am UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/2 "2024-12-01T05:31:49Z")

</div>

Hey @svoop, thanks for sharing this!

I’ve taken a look at your demo app, and it did help me discover one bug: [Hanami::DB::Testing.database\_url should apply to explicitly configured database URLs, not just ENV-detected URLs · Issue #1482 · hanami/hanami · GitHub](https://github.com/hanami/hanami/issues/1482). It was this bug that was causing this warning to print when running commands like `hanami db migrate`:

```auto
WARNING: Database svoop_demo_test expects migrations to be located within slices/admin/config/db/migrate/ but that folder does not exist.

```

The workaround for now here is to remove/comment out the explicit `datase_url` assignment line from your db provider:

```ruby
Hanami.app.configure_provider :db do
  config.gateway :default do |gw|
    # gw.database_url = "postgres://postgres@localhost/svoop_demo"
  end
end

```

With this change, Hanami will then pick up the database URL from the `DATABASE_URL` ENV var.

Two things related things happen that lead to that warning above:

1. When a `hanami db` command is run in the development environment, it also re-runs itself in the test environment, to make sure the test databases are kept in sync.
2. Our default behaviour is to append a `_test` string to a database URL when running in the test environment. We currently do this for ENV-based database URLs, but not for explicitly configured ones (hence the issue I linked above). So when the `hanami db` command executed for your app, it picked up a database URL from _both_ the ENV (since you have it in your `.env` file _as well as_ your explicitly configured URL. This led Hanami to mistakenly believe you had two databases configured instead of one, because they each had different URLs (one with `_test` appended and one not).

So by removing the explicitly configured URL for now, the warning no longer prints, because Hanami resolves just a single database URL for your app, and it knows that database is already configured via the `config/db/` folder you have:

```shell
$ bundle exec hanami db migrate
NOTE: Empty database migrations folder (config/db/migrate/) for svoop_demo
=> svoop_demo structure dumped to config/db/structure.sql in 0.0382s
NOTE: Empty database migrations folder (config/db/migrate/) for svoop_demo_test

```

But none of this addresses your concerns about `config.db.import_from_parent` and its default value.

It’s important to clarify something here. There are actually _two_ related settings:

```ruby
config.db.configure_from_parent # default is true
config.db.import_from_parent # default is false

```

`configure_from_parent` will copy DB _config_ from parent slices to child slices, but allow the child slice to have its own fully independent DB setup thereafter. So the slice will have its own relations, etc.

`import_from_parent`, on the other hand, will take the _entire DB setup_ from the parent slice and simply register it into the child slice. You would use this setting if you only want a single set of relations for your entire app (e.g. defined in `app/relations/`), and then have those relations made available in every slice.

Your demo app is fairly minimal, so it’s not clear which of these you actually want.

But here’s how you can verify the two different modes:

### `config.db.configure_from_parent = true` (our default)

To verify this, add some kind of config to the parent slice’s DB provider, for example:

```ruby
# config/providers/db.rb

Hanami.app.configure_provider :db do
  config.gateway :default do |gw|
    config.adapter :sql do |a|
      a.extension :exclude_or_null
    end
  end
end

```

Then verify that the config is also set in a child slice. So in your demo app’s case, the admin slice. Via the console:

```ruby
# Note that :exclude_or_null is here
demo[development]> app["db.gateways.default"].options[:extensions]
=> [:exclude_or_null, :caller_logging, :error_sql, :sql_comments, :pg_array, :pg_enum, :pg_json, :pg_range]

# Same for the admin slice
demo[development]> admin["db.gateways.default"].options[:extensions]
=> [:exclude_or_null, :caller_logging, :error_sql, :sql_comments, :pg_array, :pg_enum, :pg_json, :pg_range]

```

The `configure_from_parent` mode makes sure that all possible configs are taken from the parent slice and also configured on the DB setup created in child slices.

In this mode, the _config_ is copied, but the actual ROM containers are distinct to each slice:

```auto
demo[development]> app["db.rom"].object_id
=> 84940
demo[development]> admin["db.rom"].object_id
=> 91040

```

This is what allows you to create your unique relations to each slice. For example, if I updated that `create_posts.rb` migration to actually create a table, and then ran `hanami g relation posts` and `hanami g relation posts --slice=admin`, you’ll see that each slice’s ROM container only sees its own version of the posts relation:

```auto
demo[development]> app["db.rom"].relations[:posts]
=> #<Demo::Relations::Posts name=ROM::Relation::Name(posts) dataset=#<Sequel::Postgres::Dataset: "SELECT \"posts\".\"title\" FROM \"posts\"">>

demo[development]> admin["db.rom"].relations[:posts]
=> #<Admin::Relations::Posts name=ROM::Relation::Name(posts) dataset=#<Sequel::Postgres::Dataset: "SELECT \"posts\".\"title\" FROM \"posts\"">>

```

So in this arrangement:

- DB config is shared. This so that you only have to set that config in one place, rather than copy it into every slice, which is an important convenience).
- But everything else afterwards is specific to each slice.

### `config.db.import_from_parent = true` (not the default)

Now if I add this line to either `config/app.rb` or your `config/slices/admin.rb` (either place is fine, since slices will inherit their config from their parent), we see some different behaviour. The ROM containers for both the app and slices are _identical_ (the literal same object), and as such, only a single shared set of relations is available in all places.

```auto
demo[development]> app["db.rom"].object_id
=> 17380
demo[development]> admin["db.rom"].object_id
=> 17380

demo[development]> app["db.rom"].relations[:posts]
=> #<Demo::Relations::Posts name=ROM::Relation::Name(posts) dataset=#<Sequel::Postgres::Dataset: "SELECT \"posts\".\"title\" FROM \"posts\"">>
demo[development]> admin["db.rom"].relations[:posts]
=> #<Demo::Relations::Posts name=ROM::Relation::Name(posts) dataset=#<Sequel::Postgres::Dataset: "SELECT \"posts\".\"title\" FROM \"posts\"">>

```

So in this arrangement:

- DB config is centralised, by virtue of a single ROM setup being used everywhere.
- Relations are shared across all slices. This is convenient if your app is small and you don’t want the hassle of defining and managing a distinct set of relations for each slice.
- Slices still have their own repos and structs on top of those shared relations, since repos and structs those aren’t managed via the ROM container.

* * *

All of the examples above come from me working directly on your demo app, so I’m quite confident everything is working as it should. We also have tests covering these cases.

I think we could do a lot more to document these different modes. Our DB docs are still a work in progress, and we’ll add more detail when we can.

I’m really grateful you raised this though, because it’s made it clearer the need to document these better, as well as helping me find that bug! Thank you! ❤

If you have any more questions, or if you think I’ve missed something from your original report, please let me know 🙂

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/alassek/32/532_2.png) [@alassek](https://discourse.hanakai.org/u/alassek)\
**Post date:** [December 2, 2024, 12:00am UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/3 "2024-12-02T00:00:54Z")

</div>

I believe that I had confused `configure_from_parent` and `import_from_parent` in that doc page.

---

<div class="post-metadata">

**Author:** ![svoop](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/svoop/32/443_2.png) [@svoop](https://discourse.hanakai.org/u/svoop)\
**Post date:** [December 2, 2024, 12:45pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/4 "2024-12-02T12:45:10Z")

</div>

Ah, forgot about `.env` in the demo, I don’t use it on my real app. Glad the [issue #1482](https://github.com/hanami/hanami/issues/1482) bug surfaced by this mishap of mine.

As for `configure_` and `import_from_parent` though, apart from the mixup in the guides, I still have this gut feeling that there’s more.

Please take a look at my slightly revised demo. It’s still a minimalist app which sets the database URL in a provider. This time, I’ve removed the `.env` beforehand.

> **[Commits · svoop/demo](https://github.com/svoop/demo/commits/main/)**
>
> Hanami 2.2 demo app for the db issue. Contribute to svoop/demo development by creating an account on GitHub.

As you see, as soon as a slice is generated, `dev` fails to boot the app, that’s with the defaults you @timriley mentioned:

```auto
config.db.configure_from_parent # default is true
config.db.import_from_parent # default is false

```

That’s surprising because setting the database URL in the provider is “configure” and should be taken from parent by default, isn’t it?

As soon as I enable `import_from_parent` to the mix, it works fine, but relations are then shared across all slices. (No biggie for me, I probably want to keep things this way anyway.)

* * *

As a side question: For improvements on the guides, do you prefer PRs with the gist of discussions like this one (but maybe not the best of English since I’m no native speaker) or rather GitHub-issues… or neither?

---

<div class="post-metadata">

**Author:** ![timriley](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/timriley/32/621_2.png) [@timriley](https://discourse.hanakai.org/u/timriley)\
**Post date:** [December 2, 2024, 1:57pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/5 "2024-12-02T13:57:52Z")

</div>

Thanks for continuing to investigate this, @svoop. I definitely want to make sure we get to the bottom of this!

> [@svoop](#):
>
> As you see, as soon as a slice is generated, `dev` fails to boot the app

Just so I’m clear, is this what you mean:

1. I edit `config/slices/admin.rb` and comment out these lines of config, so we’re using the defaults again:

```ruby
module Admin
  class Slice < Hanami::Slice
    # config.db.configure_from_parent = true # default: true
    # config.db.import_from_parent = true # default: false
  end
end

```

2. Then when I run `hanami console` and type `admin["db.rom"]`, I see this error?

```auto
demo[development]> admin["db.rom"]
/Users/tim/.local/share/mise/installs/ruby/3.3.5/lib/ruby/gems/3.3.0/gems/hanami-2.2.1/lib/hanami/providers/db.rb:194:in `block (2 levels) in configure_gateways': A database_url for gateway default is required to start :db. (Hanami::ComponentLoadError)

```

Is that how I should be reproducing the “fails to boot” error you’re describing?

If not, please let me know what I should be doing. Once I’m clear on that, I can go and share with you what is happening and why 🙂

---

<div class="post-metadata">

**Author:** ![svoop](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/svoop/32/443_2.png) [@svoop](https://discourse.hanakai.org/u/svoop)\
**Post date:** [December 2, 2024, 2:53pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/6 "2024-12-02T14:53:45Z")

</div>

@timriley

> Is that how I should be reproducing the “fails to boot” error you’re describing?

Yes, exactly. You get the same error if you do `dev` instead of `hanami console (...)`:

```auto
15:52:19 web.1 | ! Unable to load application: Hanami::ComponentLoadError: A database_url for gateway default is required to start :db.
15:52:19 web.1 | /Users/myself/.gem/ruby/3.3.0/gems/hanami-2.2.1/lib/hanami/providers/db.rb:194:in `block (2 levels) in configure_gateways': A database_url for gateway default is required to start :db. (Hanami::ComponentLoadError)

```

(Btw: That’s on Ruby 3.3.6, I manage Rubies with direnv which builds gems per minor Ruby, not per patchlevel Ruby, hence the 3.3.0 in the path.)

---

<div class="post-metadata">

**Author:** ![svoop](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/svoop/32/443_2.png) [@svoop](https://discourse.hanakai.org/u/svoop)\
**Post date:** [December 20, 2024, 12:28pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/7 "2024-12-20T12:28:22Z")

</div>

If you have a sec for a short re on this:

> [@svoop](#):
>
> As a side question: For improvements on the guides, do you prefer PRs with the gist of discussions like this one (but maybe not the best of English since I’m no native speaker) or rather GitHub-issues… or neither?

---

<div class="post-metadata">

**Author:** ![cllns](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/cllns/32/750_2.png) [@cllns](https://discourse.hanakai.org/u/cllns)\
**Post date:** [December 20, 2024, 8:12pm UTC](https://discourse.hanakai.org/t/slices-dont-take-db-config-from-parent-by-default/1072/8 "2024-12-20T20:12:37Z")

</div>

@svoop Thanks for following up on this!

We’d prefer a PR (even with imperfect grammar/spelling, we can fix that), if you’re up for it! If you don’t have time for that, then an Issue works 🙂
