Search code examples
elixirecto

Update Postgres table using Ecto/Elixir


I have been learning Elixir lately and am wondering what is the correct syntax for solving my current issue. I am trying to update a model using Elixir and this update includes adding a value to the current value (ie amount = amount + passed_amount) and pushing a new value to an ecto array (ie transactions ++ new_transaction). Here is my latest attempt at doing this:

def add_transaction(conn, %{"coin" => coin_params}) do
        coin = Repo.get_by!(WalletCoin, ticker: coin_params["ticker"])
        coin["transactions"] ++ coin_params["transaction"]
        coin["amount"] = coin["amount"] + coin_params["amount"]
        case Repo.update(coin) do
            {ok, _coin} ->
              coins = Repo.all(WalletCoin)
              render conn, "index.json", coins: coins
        end
end

My intentions of asking this question was to get the answer and hopefully get some insight into Elixir best practices for doing this.

Thanks in advance


Solution

  • Values in Elixir are immutable. You can't just assign a new value to a field in a map like that. You'll first need to create a changeset and then change the two values:

    coin =
      Repo.get_by!(WalletCoin, ticker: coin_params["ticker"])
    
    coin = coin
      |> Ecto.Changeset.change()
      |> Ecto.Changeset.put_change(:transactions, coin.transactions ++ coin_params["transaction"])
      |> Ecto.Changeset.put_change(:amount, coin.amount + coin_params["amount"])
    

    Calling Repo.update with this should now work.