Reputation: 1437
I have a page on my app where the user selects a shipping option. I need to have their choice added to the order.total
in the database. I have the following custom method in the order.rb
model:
def update_order_from_shipping_page(shipping)
new_total = self.total + self.shipping
self.update_attributes(total: new_total)
end
And the following form in my view:
%= simple_form_for @order, url: charges_update_order_path(:shipping), method: :post do |f| %>
<div class="row">
<div class="form-inputs text-left">
<div class="form-group col-sm-6">
<%= f.collection_radio_buttons :shipping, shipping_choices, :first, :last, item_wrapper_class: :block_radio_button_collection %>
</div>
</div> <!-- form inputs -->
</div> <!-- choices row -->
<div class="row">
<%= f.button :submit, "Calculate Shipping" %>
</div>
<% end %>
And I have created the following route:
post 'charges/update_order'
I have this in my charges_controller
:
def update_order
@order = current_order
if @order.update_order_from_shipping_page(shipping)
redirect_to new_charge_path and return
else
redirect_to :back
flash[:notice] = "Something is amuck."
end
end
The radio buttons populate correctly and no console or server errors show up, but the total shown on the charges#new
page does not reflect the updates that would have been triggered by the model method. Can anyone see where I'm going wrong?
Upvotes: 0
Views: 699
Reputation: 10497
Your method receives a parameter (shipping
) but it is not using it:
def update_order_from_shipping_page(shipping)
new_total = self.total + self.shipping
self.update_attributes(total: new_total)
end
new_total
is adding self.shipping
to self.total
, instead of adding shipping
. So, unless self.shipping
already contains any data, it will not add anything.
As a result, when you call that method with:
@order.update_order_from_shipping_page(shipping)
it is not taking into account shipping
and no update to total
is done.
To fix it, change update_order_from_shipping_page
method so it adds shipping
instead of self.shipping
:
def update_order_from_shipping_page(shipping)
new_total = self.total + shipping
self.update_attributes(total: new_total)
end
UPDATE
To avoid Array can't be coerced into BigDecimal
, you need to get the correct value from the options Array
and convert it to Integer
/Float
. To accomplish that update your controller's update_order
method:
def update_order
@order = current_order
shipping = params[:order][:shipping].gsub(/[$,]/,"").to_f # new line added
if @order.update_order_from_shipping_page(shipping)
redirect_to new_charge_path and return
else
redirect_to :back
flash[:notice] = "Something is amuck."
end
end
gsub(/[$,]/,"")
is to remove currency characters ($
and ,
)
to_f
to convert String
to Float
.
Upvotes: 1