I have an issue with updating existing entries upon receiving a POST request.

The desired functionality is that a new entry gets written to the database if none exists. Otherwise a counter on the existing entry should be increased by one.

Creating a new entry works, updating the counter does not.

Here is the code and debug information:

Elixir Code

  post "/save" do
    {status, body} =
      case conn.body_params do
        %{"root" => root, "url" => url} -> {200, %{url: url, root: root}}
        _ -> {422, "fails"}
      end

    Logger.info("got a post request for analytics to be saved")
    Logger.info("#{inspect(body)}")

    # Check for status here

    %{root: root, url: url} = body

    # here we should just update directly in the database
    # without getting the value first and then counting up by 1
    new_analytics =
      case Freelytics.Repo.get_by(Freelytics.Analytics, root: root) do
        # Post not found, we build one
        nil ->
          %Freelytics.Analytics{root: root, url: url, times_visited: 1}

        analytics ->
          printer(analytics)
      end

    changeset = Freelytics.Analytics.changeset(new_analytics)
    result = Freelytics.Repo.insert_or_update(changeset)

    case result do
      {:ok, struct} ->
        Logger.info("Updated #{inspect(struct)}")
        send_resp(conn, 200, Jason.encode!(body))

      {:error, changeset} ->
        Logger.info("Updated failed for #{inspect(changeset)}")
    end
  end

Request

curl -X POST -H "Content-Type: application/json"  --data '{"root": "xyz", "url": "xyz"}' localhost:4001/save

IEX Log

15:59:17.811 [info]  got a post request for analytics to be saved

15:59:17.811 [info]  %{root: "xyz", url: "xyz"}

15:59:17.813 [debug] QUERY OK source="analytics" db=1.1ms queue=0.1ms 
SELECT a0."id", a0."url", a0."root", a0."times_visited", a0."time_spent", a0."inserted_at", a0."updated_at" FROM "analytics" AS a0 WHERE (a0."root" = $1) ["xyz"]        

15:59:17.813 [info]  Updated Object %Freelytics.Analytics{__meta__: #Ecto.Schema.Metadata<:loaded, "analytics">, id: 2, inserted_at: ~N[2019-05-11 14:38:35], root: "xyz", time_spent: nil, times_visited: 2, updated_at: ~N[2019-05-11 14:38:35], url: "xyz"}

15:59:17.813 [info]  Updated %Freelytics.Analytics{__meta__: #Ecto.Schema.Metadata<:loaded, "analytics">, id: 2, inserted_at: ~N[2019-05-11 14:38:35], root: "xyz", time_spent: nil, times_visited: 2, updated_at: ~N[2019-05-11 14:38:35], url: "xyz"}

Database query

    freelytics=# select * from analytics;
     id | root | url | times_visited | time_spent |     inserted_at     |     updated_at                                                                                     

----+------+-----+---------------+------------+---------------------+---------------------                                                                               
      2 | xyz  | xyz |             1 |            | 2019-05-11 14:38:35 | 2019-05-11 14:38:35                                                                                
    (1 row)

Am I using the function wrong? I have used this example but do not understand enough to pinpoint why the update does not happen.

0 Answers