[error] ** (Ecto.NoPrimaryKeyValueError) struct while updating. insert working fine

i am trying to update record. its giving me error. on insert its working fine.

[error] ** (Ecto.NoPrimaryKeyValueError) struct %ShopRestApis.Schema.CustomerSchema{__meta__: #Ecto.Schema.Metadata<:built, "customer">, id: nil, first_name: nil, last_name: nil, address: nil, landmark: nil, city: nil, state: nil, postcode: nil, type: nil, status: nil, mobile: nil, phone: nil, email: nil, company_name: nil, tax_code: nil, jobs: nil, inserted_at: nil, updated_at: nil} is missing primary key value
(ecto 3.12.2) lib/ecto/repo/schema.ex:1078: anonymous fn/3 in Ecto.Repo.Schema.add_pk_filter!/2

but i have id in changes

[(shop_rest_apis 0.1.0) lib/shop_rest_apis/context/customer_context.ex:67: ShopRestApis.Context.CustomerContext.update/2]
value #=> #Ecto.Changeset<
  action: nil,
  changes: %{
    id: "27efc595-dba9-4d9a-8a16-a4fd0d733c17",
    status: "Active",
    type: "Private",
    mobile: "+39,350577777",
    first_name: "test"
  },
  errors: [],
  data: #ShopRestApis.Schema.CustomerSchema<>,
  valid?: true,
  ...
>

my update function

  def update(%CustomerSchema{} = data, attrs) do
    data
    |> CustomerSchema.changeset(attrs)
    |> Repo.update()
  end

controller

def update(conn, params) do
    customer =
      ContextAliasController.get!(params["id"])

    with {:ok, %SchemaAliasController{} = customer} <-
           ContextAliasController.update(
             customer,
             params
           ) do
      render(conn, :show, customer: customer)
    end
  end

on schema i have uuid as primary key

  @primary_key {:id, :binary_id, autogenerate: false}
  @foreign_key_type :binary_id

Can you show the CustomerSchema.changeset function? Maybe also ShopRestApis.Context.CustomerContext.update?

defmodule ShopRestApis.Schema.CustomerSchema do
  use Ecto.Schema
  import Ecto.Changeset

  @fields [
    :id,
    :first_name,
    :last_name,
    :address,
    :landmark,
    :city,
    :state,
    :postcode,
    :mobile,
    :phone,
    :email,
    :company_name,
    :tax_code,
    :type,
    :status,
    :jobs,
    :shop_id
  ]
  @validation_fields [:first_name, :mobile, :type, :status]

  @primary_key {:id, :binary_id, autogenerate: false, read_after_writes: true}
  @foreign_key_type :binary_id
  schema "customer" do
    field :first_name, :string
    field :last_name, :string
    field :address, :string
    field :landmark, :string
    field :city, :string
    field :state, :string
    field :postcode, :string
    field :type, :string
    field :status, :string
    field :mobile, :string
    field :phone, :string
    field :email, :string
    field :company_name, :string
    field :tax_code, :string
    field :jobs, :integer

    belongs_to :shop, ShopRestApis.Schema.ShopSchema,
      foreign_key: :shop_id,
      type: @foreign_key_type

    timestamps(type: :utc_datetime)
  end

  @doc false
  def changeset(_, attrs) do
    %__MODULE__{}
    |> cast(attrs, @fields)
    |> validate_required(@validation_fields)
  end
end

update function

  def update(%CustomerSchema{} = data, attrs) do
    data
    |> CustomerSchema.changeset(attrs)
    |> Repo.update_all()
  end

Update isn’t going to work unless you use the first argument to changeset :stuck_out_tongue:

3 Likes

i dont know what to say. stupid mistake. thank you very much.