Creating a form for two schemas, one of the schemas has unsafe_validate_unique

I have two schemas: User and Clinic, they both have different validations. User for example uses a unsafe_validate_unique for the email.

I’ve created an embedded_schema to act as backing for this single form, and my idea was to call both schemas’s changeset to validate the submitted data.

  embedded_schema do
    field(:email, :string)
    field(:password, :string, virtual: true, redact: true)
    field(:timezone, :string)
    field(:phone_number, :string)

    field(:name, :string)
    field(:website, :string)
    field(:specialty, :string)
    field(:state, :string)
    field(:staff_size, :string)
    field(:patient_size, :string)
  end

  def changeset(schema, attrs \\ %{}) do
    user_changeset = User.clinic_user_registration_changeset(schema, attrs) |> IO.inspect()
    clinic_changeset = Clinic.changeset(schema, attrs) |> IO.inspect()

    # TODO, copy both changeset's changes into  the single changeset and return that.
    user_changeset
  end

However this fails to even load the page, with this exception:

unsafe_validate_unique/4 does not work with embedded schemas unless the :query option is specified, got: #MyAppWeb.ClinicOnboardingLive.Schema<id: nil, email: nil, timezone: nil, phone_number: nil, name: nil, website: nil, specialty: nil, state: nil, staff_size: nil, patient_size: nil, …>

I tried to add the query option to the function but I get a different error now:

  defp maybe_validate_unique_email(changeset, opts) do
    if Keyword.get(opts, :validate_email, true) do
      changeset
      |> unsafe_validate_unique(:email, MyApp.Repo, query: from(u in MyApp.Accounts.User))
      |> unique_constraint(:email)
    else
      changeset
    end
  end

cannot add constraint to changeset because it does not have a source, got: #MyAppWeb.ClinicOnboardingLive.Schema<id: nil, email: nil, timezone: nil, phone_number: nil, name: nil, website: nil, specialty: nil, state: nil, staff_size: nil, patient_size: nil, …>

Now I’m stuck, appreciate any tips!

How about splitting up the changeset between commonly applicable stuff and things that won’t work without the db involved?

Maybe this is a simple thought, but can you use validate_change and fire the query in the callback? I think it’s, what unsafe_validate_unique does anyways.