Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reusable embeds in use Params.Schema, %{} #15

Open
astery opened this issue Nov 25, 2016 · 3 comments
Open

Reusable embeds in use Params.Schema, %{} #15

astery opened this issue Nov 25, 2016 · 3 comments

Comments

@astery
Copy link
Contributor

astery commented Nov 25, 2016

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
@vic
Copy link
Owner

vic commented Dec 18, 2016

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.

@astery
Copy link
Contributor Author

astery commented Dec 19, 2016

Ok, I will try it in this week.

@moxley
Copy link

moxley commented Jul 24, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants