I tried to update a record, but it had no effect

I am new to elixir and phoenix framework, and doing a little project to learn them. pls help. thanks.

Here is the update action and schema

def update(conn, %{"id" => id, "store" => store_params}) do
    store = Repo.get!(Store, id)
    #Logger.debug "Var value: #{inspect(store)}"
    changeset = Ecto.Changeset.change(store, store_params)
    Logger.debug "Var value: #{inspect(changeset)}"
    case Repo.update(changeset) do
      {:ok, store} ->
        Logger.debug "Var value: #{inspect(store)}"
        conn
        |> put_flash(:info, "#{store.name} updated!")
        |> redirect(to: Routes.store_path(conn, :index))
      {:error, changeset} ->
        render(conn, "update.html", changeset: changeset, store: store)
    end
  end
defmodule Esale.Store do
  use Ecto.Schema
  import Ecto.Changeset


  schema "store" do
    field :name, :string
    field :platform, :string
    field :token, :string
    field :token_expire_date, :date
    timestamps()
  end

  @doc false
  def changeset(store, attrs) do
    store
    |> cast(attrs, [])
    |> validate_required([])
  end
end

Here is the log detail, i didn’t find any update sql log at all.

[debug] Processing with EsaleWeb.StoreController.update/2
  Parameters: %{"_csrf_token" => "DxQjdWEwXwEVMV0HBQMxcAwaZwhBAAAAzZlCYH4vFBoeIPG6di1kxQ==", "_method" => "put", "_utf8" => "鉁?, "id" => "1", "store" => %{"name" => "way", "platform" => "Ebay", "token" => "666", "token_expire_date" =>"2018-12-19"}}
  Pipelines: [:browser]
[debug] QUERY OK source="store" db=0.0ms
SELECT s0."id", s0."name", s0."platform", s0."token", s0."token_expire_date", s0."inserted_at", s0."updated_at" FROM "store" AS s0 WHERE (s0."id" = $1) [1]
[debug] Var value: #Ecto.Changeset<action: nil, **changes: %{"name" => "way", "platform" => "Ebay", "token" => "666", "token_expire_date" => "2018-12-19"},** errors: [], data: #Esale.Store<>, valid?: true>
[debug] Var value: %Esale.Store{__meta__: #Ecto.Schema.Metadata<:loaded, "store">, id: 1, inserted_at: ~N[2018-12-19 12:58:35], name: "way", platform: "Ebay", token: "1111", token_expire_date: ~D[2018-12-19], updated_at: ~N[2018-12-19 1
2:58:35]}
[info] Sent 302 in 0碌s
[info] GET /store
[debug] Processing with EsaleWeb.StoreController.index/2
  Parameters: %{}
  Pipelines: [:browser]
[debug] QUERY OK source="store" db=0.0ms
SELECT s0."id", s0."name", s0."platform", s0."token", s0."token_expire_date", s0."inserted_at", s0."updated_at" FROM "store" AS s0 []
[info] Sent 200 in 0碌s

If You don’t cast your data, your changeset will have no fields to change.

Try this

  @doc false
  def changeset(store, attrs) do
    store
    |> cast(attrs, [:name, :platform, :token, :token_expiry])
    |> validate_required([:name])
  end

In cast You should add all your fields, and in validate_required You should put mandatory fields.

PS: Usually You should redirect to edit in case of error.

7 Likes

So change what @kokolegorille said but also change this line in your controller

changeset = Ecto.Changeset.change(store, store_params)

to use the Esale.Store.changeset/2 like:

changeset = Esale.Store.changeset(store, store_params)
5 Likes