Overwritting a config section partially

In config/config.exs I have this:

  config :my_config_section, MyApp.Module1,
    a: "dfsafds",
    b: 1234,
    c: "aaaaaa",
    d: true

In config/dev.exs I want to overwritte only 1-2 keys of ‘my_config_section’. Without having to specify all the keys again.

Is it possible?

Yes. It should just work. Mix config will merge values recursively instead of overriding them.

3 Likes

Beware though, only keyword lists are merged recursively:

config :foo, :config_key,
  atom: :just_an_atom,
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
  map: %{list: ["hello", "config"]}

config :foo, :config_key,
  new_atom: :this_is_new,
  atom: :replaced_atom,
  kwlist: [baz: 1, quux: 2],
  map: %{}

$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[
  new_atom: :this_is_new,
  atom: :replaced_atom,
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}, baz: 1, quux: 2],
  map: %{}
]

If for some reason maps are used as config values, they won’t be merged; the latest value will simply override anything set before it:

config :foo, :config_key, %{
  atom: :just_an_atom,
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
  map: %{list: ["hello", "config"]}
}

config :foo, :config_key, %{
  new_atom: :this_is_new
}

$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
%{new_atom: :this_is_new}

The same reasoning applies when overriding values one key at a time. So, using keywords, we can override a single key later like this

config :foo, :config_key,
  atom: :just_an_atom,
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
  map: %{list: ["hello", "config"]}

config :foo, :config_key, kwlist: [new_key: nil]

$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[
  atom: :just_an_atom,
  map: %{list: ["hello", "config"]},
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}, new_key: nil]
]

but if a map was used initially, it will be overriden:

config :foo, :config_key, %{
  atom: :just_an_atom,
  kwlist: [foo: [a: 1, b: 2], tuple: {1, 2, 3}],
  map: %{list: ["hello", "config"]}
}

config :foo, :config_key, kwlist: [new_key: nil]

$ iex -S mix
iex(1)> Application.get_env(:foo, :config_key)
[kwlist: [new_key: nil]]
3 Likes