0

I have an instance where I am recording prices for water from vendors. My vendor model has :price. However, I want to give users the option to input a price for different volumes, and do the simple division for them rather than having them to do it. In other words, users should be able to input $1.99 per liter or $3.99 for a gallon and so on. To do this, I need a virtual attribute in my form for :unit, since I don't want to be storing units in the table. Everything works well, except that I cannot seem to update vendor_params[:price] before I update the record or create a new record. This seems like it should be a cake walk, but I Googled most of the day and can't figure out how to make it work.
Here is what I have:

Model:

class Vendor < ActiveRecord::Base
   attr_accessor :unit
...
end

Form:

<%= form_for(@vendor) do |f| %>
...
<div class="field">
    <%= f.label :price %><br>
    <%= f.text_field :price %>
    <%= select( "unit", "id", { "1 Liter" => "1", "Bottle (2 liters)" => "2", "Jerry Can  (20 liters)" => "20"}) %>
</div>
...
<% end %>

Controller:

...
def update 

vendor_params[:price] = vendor_params[:price].to_f/params[:unit][:id].to_f

respond_to do |format|
  if @vendor.update(vendor_params)
    format.html { redirect_to @vendor, notice: 'Vendor was successfully updated.' }
    format.json { head :no_content }
  else
    format.html { render action: 'edit' }
    format.json { render json: @vendor.errors, status: :unprocessable_entity }
  end
end
...
end

I know that vendor_params[:price].to_f/params[:unit][:id].to_f returns the correct value. I just can't seem to assign that value to vendor_params[:price] before I update the record. I also tried the following which throws an error:

@vendor_params[:price] = vendor_params[:price].to_f/params[:unit][:id].to_f

It seems like this should be trivial! I guess I could use form_tag instead of form_for, but that seems odd when updating the full record. (The edit form has all fields for all the object attributes.) Anywho, I'm open to ideas and suggestions.
Thanks!!

1 Answer 1

2

If vendor_params is a strong_params method (which I'm assuming it is), it actually creates a new hash. So when you alter vendor_params... you're not actually changing your original params hash.

OK, why isn't vendor_params changing though... I dont care about params? WELL, vendor_params still points the original params hash assuming it looks something like:

def vendor_params
  params.require(:vendor).permit(:price)
end

I think the link below is a similar issue and may present a useful solution. Hope I understood your problem correctly!

Modify ruby hash in place( rails strong params)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @rsahai91! Your explanation and link gave me an idea how to fix it. I basically created an instance variable like so: vp = vendor_params and passed the form hash vp[:price] = vendor_params[:price].to_f/params[:unit][:id].to_f then just updated with the instance variable: @vendor.update(vp)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.