Assocation .build clears amount if association called during setup
nitsujri opened this issue · 2 comments
TL;DR
If a model association is called during .build
for setting with_model_currency
, the column_cents
gets reset to 0.
Example
https://github.com/nitsujri/money-build-issue
To run it, load the rails console
and run User.run_example
.
Details
It will run through showing .build
works fine if we don't call the assocation, user.currency
, during with_model_currency
, but then if we do call an association, amount_cents
becomes zero.
The problem line is this. The only difference is a random user.currency
that has no bearing on the final output.
After build, setting amount
works just fine as we all would expect.
Closing
This specifically caught us during a accepts_nested_attributes_for
form. I left all the deprecations in, so the output is a bit messy.
I can also get a similar situation with u=User.create; Purchase.new(user: u, amount: '222')
so it's build/new initializer? I'm just guessing at this point though.
Thank you!
Thanks for this fantastic set of gems!
@semmons99 hi. This issue still persists for me. I'm on money-rails (1.15.0)
. For me my price_cents
gets reset to 0 in a nested attribute record creation. price_cents
is a monitized field. Nested attribute structure is as such -
model A has many model B, model A accepts_nested_attributes
for Bs
model B has many model C, model B accepts_nested_attributes
for Cs
model C has a field price_cents
, bigint
, default: 0
.
While record creation in a nested setting the rails build
method sets price_cents
to 0, however in update this doesn't happen.
I have the same issue, did anyone find a fix for that? Nested attributes ignore the price
attribute, but it works with price_cents
.
The price
param will work if the order is being created or if the order item already exists. If the order exists and a new order item gets added, price
will not work.
My workaround for now is to manually change the price to cents. For example:
order_params = params.require(:order).permit(
:name,
order_items_attributes: [ :id, :name, :quantity, :unit_price, :_destroy ]
)
if order_params[:order_items_attributes].present?
order_params[:order_items_attributes].each do |key, order_item_params|
order_item_params[:unit_price_cents] = Money.from_amount(order_item_params[:unit_price].to_f).cents
order_item_params.delete(:unit_price)
end
end
order_params