slouchpie

slouchpie

Updating money amount in database using `:inc`

@kip You might know if this is possible or not.

I have been experimenting with different ways of updating a balance field in the database that is of the usual Money type.

Consider this:

    Multi.update_all(
      multi,
      :wallet,
      fn _ ->
        from(w in Wallet,
          where: w.id == ^wallet_id,
          update: [inc: [balance: type(^amount, ^Money.Ecto.Composite.Type.cast_type())]]
        )
      end,
      []
    )

This results in an error:

     ** (Postgrex.Error) ERROR 42883 (undefined_function) operator does not exist: money_with_currency + money_with_currency
     
         query: UPDATE "wallets" AS w0 SET "balance" = w0."balance" + $1::money_with_currency WHERE (w0."id" = $2)
     
         hint: No operator matches the given name and argument types. You might need to add explicit type casts.

I have run the “aggregate functions for money” migration although I didn’t think it would help since this is +, not sum.

I think maybe this kind of syntax just isn’t possible? Can anyone confirm?

Marked As Solved

kip

kip

ex_cldr Core Team

I’ve just published ex_money_sql version 1.5.0 that adds support for the Postgres + operator for :money_with_currency types. I believe that will also support the query you described above.

To install the required functions in Postgres the readme now says:

Plus operator +

ex_money defines a migration generator which, when migrated to the database with mix ecto.migrate, supports the + operator for :money_with_currency columns. The steps are:

  1. Generate the migration by executing mix money.gen.postgres.plus_operator

  2. Migrate the database by executing mix ecto.migrate

  3. Formulate an Ecto query to use the + operator

  iex> q = Ecto.Query.select Item, [l], type(fragment("price + price"), l.price)
  #Ecto.Query<from l0 in Item, select: type(fragment("price + price"), l0.price)>
  iex> Repo.one q
  [debug] QUERY OK source="items" db=5.6ms queue=0.5ms
  SELECT price + price::money_with_currency FROM "items" AS l0 []
  #Money<:USD, 200>]

Let me know if you have any feedback and please file any bugs on the issue tracker.

12
Post #2

Also Liked

kip

kip

ex_cldr Core Team

Good to hear! Was a fun Saturday morning puzzle for me. And always good to be reminded how amazing Postgres is!

kip

kip

ex_cldr Core Team

ex_money_sql is the library that implements database support for Money.t types. After that, its Postgres (or MySQL potentially or some other database) that is doing all the work.

The + operator can be overloaded in Postgres and the implementation of that for a :money_with_currency type is here

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Other popular topics Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement