diff --git a/lib/ecto/schema.ex b/lib/ecto/schema.ex index b1bec14ccf..7e52f245c5 100644 --- a/lib/ecto/schema.ex +++ b/lib/ecto/schema.ex @@ -2066,7 +2066,8 @@ defmodule Ecto.Schema do store_mfa_autogenerate!(mod, name, type, gen) autogenerate_opts when is_list(autogenerate_opts) -> - store_mfa_autogenerate!(mod, name, type, {type, :autogenerate, [autogenerate_opts]}) + mfa = {autogenerate_module(type), :autogenerate, [autogenerate_opts]} + store_mfa_autogenerate!(mod, name, type, mfa) true -> store_type_autogenerate!(mod, name, source || name, type, pk?) @@ -2635,6 +2636,14 @@ defmodule Ecto.Schema do defp composite?(_type, _name), do: false + defp autogenerate_module({:parameterized, {type, _params}}), do: type + + defp autogenerate_module({composite, nested_type} = type) do + if Ecto.Type.composite?(composite), do: autogenerate_module(nested_type), else: type + end + + defp autogenerate_module(type), do: type + defp store_mfa_autogenerate!(mod, name, type, mfa) do if autogenerate_id?(type) do raise ArgumentError, ":autogenerate with {m, f, a} not supported by ID types" diff --git a/test/ecto/repo/autogenerate_test.exs b/test/ecto/repo/autogenerate_test.exs index def7a8db0a..6e559b6f12 100644 --- a/test/ecto/repo/autogenerate_test.exs +++ b/test/ecto/repo/autogenerate_test.exs @@ -133,6 +133,38 @@ defmodule Ecto.Repo.AutogenerateTest do end end + defmodule AutogenerateOptionsType do + use Ecto.Type + + def type, do: :string + def cast(value), do: {:ok, value} + def load(value), do: {:ok, value} + def dump(value), do: {:ok, value} + def autogenerate(opts), do: Keyword.fetch!(opts, :value) + end + + defmodule ParameterizedAutogenerateOptionsType do + use Ecto.ParameterizedType + + def init(opts), do: opts + def type(_params), do: :string + def cast(value, _params), do: {:ok, value} + def load(value, _loader, _params), do: {:ok, value} + def dump(value, _dumper, _params), do: {:ok, value} + def autogenerate(opts), do: Keyword.fetch!(opts, :value) + end + + defmodule AutogenerateOptionsSchema do + use Ecto.Schema + + schema "autogenerate_options_schema" do + field :parameterized, ParameterizedAutogenerateOptionsType, + autogenerate: [value: "parameterized"] + + field :composite, {:array, AutogenerateOptionsType}, autogenerate: [value: ["composite"]] + end + end + ## Autogenerate @uuid "30313233-3435-4637-9839-616263646566" @@ -179,6 +211,13 @@ defmodule Ecto.Repo.AutogenerateTest do assert byte_size(schema.uuid_v7) == 36 end + test "autogenerates parameterized and composite types with options" do + schema = TestRepo.insert!(%AutogenerateOptionsSchema{}) + + assert schema.parameterized == "parameterized" + assert schema.composite == ["composite"] + end + ## Timestamps test "sets inserted_at and updated_at values" do