You have specified a default value for a type that cannot be explicitly converted to an Ecto default

I’m having some trouble with EctoMigrationDefault – probably because I’m a novice with Elixir custom types and protocols, and I’m clearly getting something a bit wrong here.

10:09:57.706 [warning] You have specified a default value for a type that cannot be explicitly
converted to an Ecto default:

  `[:value_add, :non_value_add]`

The default value in the migration will be set to `nil` and you can edit
your migration accordingly.

To prevent this warning, implement the `EctoMigrationDefault` protocol
for the appropriate Elixir type in your Ash project, or configure its
default value in `migration_defaults` in the postgres section. Use `\"nil\"`
for no default.

This is coming from:

# activity_stereotype.ex
  attributes do
    attribute :allowed_types, {:array, COE.Types.ActivityTypes} do
      allow_nil? false
      default COE.Types.ActivityTypes.values
    end
    ...
  end

Trying to resolve this using EctoMigrationDefault I ended up here:

defmodule COE.Types.ActivityTypes do
  @moduledoc ~S"""
  Provides the allowed types for an `COE.Walk.ActivityStereotype`. Types are typically defined as either value add or non-value add.
  """

  use Ash.Type.Enum, values: [:value_add, :non_value_add] # ~w(value_add non_value_add)a

  @type t :: [:atom] 

  def to_string, do: inspect(Enum.map(values(), &(to_string(&1))))
end

defimpl EctoMigrationDefault, for: COE.Types.ActivityTypes do
  def to_default(t), do: to_string(t)
end

Like I said, a novice with custom types (and protocols). With the above in place, I still get the warning about “a type that cannot be explicitly converted to an Ecto default.”

Footnote: I prefer the EctoMigrationDefault approach, but I did note that I can shut up the warning by adding migration_defaults [allowed_types: COE.Types.ActivityTypes.to_string] to the postgres block. But I don’t like how that creates an extra dependency on having a postgres block.

Honestly, the EctoMigrationDefault isn’t the right answer here. You’d have to implement the protocol for arrays generically. We’re kind of moving away from EctoMigrationDefault in general anyway. I would do this:

postgres do
   migration_defaults [allowed_types: "[:value_add, :non_value_add]"]
end

EDIT: sorry, just saw your footnote. I’d advise against using EctoMigrationDefault in general unless the value you’re using it for is a struct (like Money) and the type is not in your control (because if it is there is a callback you can use to set the default value).

1 Like