Changeset with external variable validation error

I have a model and a changeset like these, however when I want to compare quantity with max_quantity (both are decimal).

This error appears:

unknown field max_quantity. Only fields, embeds and associations
defmodule Finance.Asset do
  use Ecto.Schema
  import Ecto.Changeset
  alias Finance.Asset

  schema "asset" do
    belongs_to :entity, Finance.Entity
    belongs_to :denomination, Finance.Denomination
    belongs_to :wallet, Finance.Wallet
    field :quantity, :decimal
    field :usd_input_value, :decimal
    field :tx_id, :string
    field :comment, :string

    timestamps(updated_at: false)
  end

    def newInputAssetInTx(%Asset{} = asset, attrs) do
    asset
    |> cast(attrs, [:entity_id, :wallet_id, :denomination_id, :max_quantity, :quantity, :usd_input_value, :comment, :inserted_at])
    |> validate_number(:quantity, less_than_or_equal_to: :max_quantity)
  end

end

This is the changeset input

    newAssetInTxChangeset = Asset.newInputAssetInTx(%Asset{}, %{entity_id: conn.params["new_tx"]["from_entity_id"],
                                                                wallet_id: conn.params["new_tx"]["from_wallet_id"],
                                                                denomination_id: conn.params["new_tx"]["from_denomination_id"],
                                                                max_quantity: balance,                                                               
                                                                quantity: conn.params["new_tx"]["from_quantity"],
                                                                usd_input_value: conn.params["new_tx"]["from_usd_input_value"],
                                                                comment: conn.params["new_tx"]["from_to_comment"],
                                                                inserted_at: conn.params["new_tx"]["ts"]})

You don’t have :max_quantity defined in your schema. You can add a “virtual” field for it:

schema "asset" do
  belongs_to :entity, Finance.Entity
  belongs_to :denomination, Finance.Denomination
  belongs_to :wallet, Finance.Wallet
  field :quantity, :decimal
  field :usd_input_value, :decimal
  field :tx_id, :string
  field :comment, :string
  field :max_quantity, :decimal, virtual: true # <-- here

  timestamps(updated_at: false)
end

Then the error will probably go away.

From https://hexdocs.pm/ecto/Ecto.Schema.html:

[…] schemas can also have virtual fields by passing the virtual: true option. These fields are not persisted to the database and can optionally not be type checked by declaring type :any.

1 Like

The max_quantity can now be casted. But I got the issue of comparing two decimals, seems like validate_number doesn’t work, can I validate using Decimal.cmp(x, y), o something like this in the changeset? Or how do I compare two decimals?

This error appears:
no function clause matching in Decimal.new