params
params copied to clipboard
Reusable embeds in `use Params.Schema, %{}`
Just as suggestion or maybe I missing something and this can be already achieved:
defmodule SomeIdentityParams do
use Params.Schema
import App.Params.Helpers
@fields ~w(id code)
schema do
field :id, :id
field :code, :string
# more here
end
def changeset(changeset, params) do
cast(changeset, params, @fields)
|> at_least_one_should_be_present([:id, :code])
end
end
# this one looks fine
defmodule SomeControllerParams do
use Params.Schema
@fields ~w(tarif_id some_identity)a
schema do
field :tarif_id, :id
embeds_one :some_identity, SomeIdentityParams
end
def changeset(cs, params) do
cast(cs, params, @fields)
|> validate_required(@fields)
|> cast_embed(:passenger, required: true)
end
end
# but it can be much shorter
defmodule SomeControllerParams do
use Params.Schema, %{
tarif_id: :id,
some_identity: SomeIdentityParams
}
end
Hey, using SomeIdentityParams directly would be nice, could you provide a PR? The only thing would be to check if the symbol resembles a module (ie its capitalized) then use embeds_one for it.
Ok, I will try it in this week.
The challenge is that it is difficult to differentiate between an Ecto type and an Ecto schema.
Using your example, right now, params supports something like this:
use Params.Schema, %{
tarif_id: :id,
some_identity: Ecto.UUID
}
Ecto.UUID is an Ecto type, not a schema.
So if you were to assign SomeIdentityParams to :some_identity, how would params know it's a schema and not a type? If this was evaluated at runtime, it would be easy: call Kernel.function_exported?(SomeIdentityParams, :__schema__, 1) to discover that SomeIdentityParams is a schema. But it's not evaluated at runtime. It's evaluated at compile time. SomeIdentityParams is not loaded at compile time, and therefore the __schema__/1 function will not be exported.