View Source Pow.Ecto.Schema behaviour (Pow v1.0.38)

Handles the Ecto schema for user.

The macro will create a @pow_fields module attribute, and append fields to it using the attributes from Pow.Ecto.Schema.Fields.attrs/1. Likewise, a @pow_assocs module attribute is also generated for associations. The pow_user_fields/0 macro will use these attributes to create fields and associations in the ecto schema.

The macro will add two overridable functions to your module; changeset/2 and verify_password/2. See the customization section below for more.

The following helper functions are added for changeset customization:

  • pow_changeset/2,
  • pow_verify_password/2
  • pow_user_id_field_changeset/2
  • pow_password_changeset/2,
  • pow_current_password_changeset/2,

Finally pow_user_id_field/0 function is added to the module that is used to fetch the user id field name.

A @pow_config module attribute is created containing the options that were passed to the macro with the use Pow.Ecto.Schema, ... call.

See Pow.Ecto.Schema.Changeset for more.

Usage

Configure lib/my_project/users/user.ex the following way:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema,
    user_id_field: :email,
    password_hash_verify: {&Pow.Ecto.Schema.Password.pbkdf2_hash/1,
                            &Pow.Ecto.Schema.Password.pbkdf2_verify/2},
    password_min_length: 8,
    password_max_length: 4096

  schema "users" do
    field :custom_field, :string

    pow_user_fields()

    timestamps()
  end

  def changeset(user_or_changeset, attrs) do
    pow_changeset(user_or_changeset, attrs)
  end
end

Remember to add user: MyApp.Users.User to your configuration.

Configuration options

  • :user_id_field - the field to use for user id. This value defaults to :email, and the changeset will automatically validate it as an e-mail.

Customize Pow fields

Pow fields can be overridden if the field name and type matches:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema

  schema "users" do
    field :encrypted_password, :string
    field :password_hash, :string, source: :encrypted_password

    pow_user_fields()

    timestamps()
  end
end

The same holds true for associations:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema

  @pow_assocs {:belongs_to, :invited_by, __MODULE__, []}
  @pow_assocs {:has_many, :invited, __MODULE__, []}

  schema "users" do
    belongs_to :invited_by, __MODULE__, foreign_key: :user_id

    pow_user_fields()

    timestamps()
  end
end

An @after_compile callback will emit IO warning if there are missing fields or associations. You can forego the pow_user_fields/0 call, and write out the whole schema instead:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema, user_id_field: :email

  schema "users" do
    field :email,            :string
    field :password_hash,    :string
    field :current_password, :string, virtual: true
    field :password,         :string, virtual: true
    field :confirm_password, :string, virtual: true

    timestamps()
  end
end

If you would like these warnings to be raised during compilation you can add elixirc_options: [warnings_as_errors: true] to the project options in mix.exs.

The warning is also emitted if the field has an invalid primitive Ecto type. It'll not be emitted for custom Ecto types.

Customize Pow changeset

You can extract individual changeset functions to modify the changeset flow entirely. As an example, this is how you can remove the validation check for confirm password in the changeset function:

defmodule MyApp.Users.User do
  use Ecto.Schema
  use Pow.Ecto.Schema

  import Pow.Ecto.Schema.Changeset, only: [new_password_changeset: 3]

  # ...

  def changeset(user_or_changeset, attrs) do
    user_or_changeset
    |> pow_user_id_field_changeset(attrs)
    |> pow_current_password_changeset(attrs)
    |> new_password_changeset(attrs, @pow_config)
  end
end

Note that the changeset functions in Pow.Ecto.Schema.Changeset require the Pow ecto module configuration that is passed to the use Pow.Ecto.Schema, ... call. This can be fetched by using the @pow_config module attribute.

Summary

Functions

Normalizes the user id field.

A macro to add fields from the @pow_fields module attribute generated in __using__/1.

Get user id field key from changeset or configuration.

Callbacks

@callback changeset(Ecto.Schema.t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
Link to this callback

verify_password(t, binary)

View Source
@callback verify_password(Ecto.Schema.t(), binary()) :: boolean()

Functions

Link to this function

filter_new_fields(fields, existing_fields)

View Source
This function is deprecated. No longer public function.
Link to this function

normalize_user_id_field_value(value)

View Source
@spec normalize_user_id_field_value(binary()) :: binary()

Normalizes the user id field.

Keeps the user id field value case insensitive and removes leading and trailing whitespace.

Link to this macro

pow_user_fields()

View Source (macro)

A macro to add fields from the @pow_fields module attribute generated in __using__/1.

The @pow_fields are populated by Pow.Ecto.Schema.Fields.attrs/1, and will have at minimum the following fields:

  • :email (if not changed with :user_id_field option)
  • :password_hash
  • :current_password (virtual)
  • :password (virtual)
@spec user_id_field(Ecto.Changeset.t() | Pow.Config.t()) :: atom()

Get user id field key from changeset or configuration.

Defaults to :email.