0

I have sample parameter below:

Parameters: {
          "utf8"=>"✓",
          "authenticity_token"=>"xxxxxxxxxx",
          "post" => {
              "product_attributes" => {
                  "name"=>"Ruby",
                  "product_dtls_attributes" => {
                      "0"=>{"price"=>"12,333.00"},
                      "1"=>{"price"=>"111,111.00"}
                  },
              },
          "content"=>"Some contents here."
        }

Now, the scenario is, I cannot get the price exact value in model.

Instead of:

  1. price = 12,333.00
  2. price = 111,111.00

I get:

  1. price = 12.00
  2. price = 11.00

And now here is what I did in my code:

before_validation(on: :create) do
  puts "price = #{self.price}" # I also tried self.price.to_s, but didn't work.
end

UPDATE:

(I am trying do to here is to get the full value and strip the comma).

before_validation(on: :create) do
  puts "price = #{self.price.delete(',').to_f}" # I also tried self.price.to_s, but didn't work.
end

Note:

column price is float

The question is, how can I get the exact value of params price. Thanks!

HashRocket
  • 778
  • 1
  • 5
  • 15
  • @VtrKanna, I am trying to fetch the whole value not rounding of or something. But, thanks then. – HashRocket Mar 17 '16 at 07:52
  • No, you are not getting what I want to do. It's not on parsing. It is on getting the full value of `price`. – HashRocket Mar 17 '16 at 08:02
  • Have you tried to get the exact value in the controller and pass parameter to your model? –  Apr 02 '16 at 11:39

4 Answers4

1

Looking at the 'price' parameter you provided:

"price"=>"12,333.00"

The problem is with the comma.

For example:

irb(main):003:0> "12,333.00".to_i
=> 12

But you can fix that:

Example:

irb(main):011:0> "12,333.00".tr(",", "_").to_i
=> 12333

The key point is replacing the comma with an underscore. The reason is that 12_333 is the same integer as 12333 (the underscores are ignored). You could just remove the comma with tr(",", "") as well. In this case, you could replace tr with gsub and have the same effect.

By the way, are you aware that your validation method is not doing anything besides printing? Anyway, a before_validation method is not the right approach here because the number will already have been incorrectly converted when the code reaches this point. Instead, you can override the setter on the model:

class MyModel
  def price=(new_price)
    if new_price.is_a?(String)
      new_price = new_price.tr(",", "")
    end 
    super(new_price)
  end
end
max pleaner
  • 26,189
  • 9
  • 66
  • 118
  • This is not getting the full value of `price`. – HashRocket Mar 17 '16 at 08:05
  • i dont know what's going on in the rest of your rails app, but overriding the model setter to remove the comma is the gist of this. you should be able to test it in rails console. also, leaving a comment saying it's not working without giving any further information is not productive. – max pleaner Mar 17 '16 at 10:06
0

You can do it like this too:

2.1.1 :002 > "12,333.00".gsub(',', '').to_f
 => 12333.0

This will replace the comma and if you have any decimal value then too it will interpret it:

2.1.1 :003 > "12,333.56".gsub(',', '').to_f
 => 12333.56 
Deepesh
  • 6,138
  • 1
  • 24
  • 41
  • The problem is not in stripping comma. But to get the full value of `price`. I only updated the question because I guess @user1934428 didn't get what I want to do. – HashRocket Mar 17 '16 at 08:04
  • So are you not getting using the above? It will replace the comma and when you do `to_f` it will change it to `float` without loosing any value. What else is missing? – Deepesh Mar 17 '16 at 08:28
0

The solution I made is to handle it on controller. Iterate the hash then save it. Then it get the proper value which I want to get and save the proper value.

Iterate the following hash and save.

"post" => {
          "product_attributes" => {
              "name"=>"Ruby",
              "product_dtls_attributes" => {
                  "0"=>{"price"=>"12,333.00"},
                  "1"=>{"price"=>"111,111.00"}
              },
          },
      "content"=>"Some contents here."

I can't get the full value of price in model because of comma separator. This comma separator and decimal points + decimal places is made by gem.

HashRocket
  • 778
  • 1
  • 5
  • 15
-1

Price is float, but your data contains a non-numeric character (comma, ","). When the field is converted to a float, parsing likely stops at this character and returns just 12.

I had expected an error to be thrown, though.

I suggest you remove the comma before putting it into the database.

user1934428
  • 19,864
  • 7
  • 42
  • 87
  • Yes, that's why I want to strip it before validation and saving. I'll update my code to clear what should I want to do. – HashRocket Mar 17 '16 at 07:49
  • I was not aware that you are looking for help **how** to remove the comma, since you didn't mention this in your original posting. I thought you only want to know, why you got the result. ... and I wondered why my response (which, at least with respect to your original posting, seems to be correct) was downvoted. – user1934428 Mar 17 '16 at 14:56
  • One more point: If you want the **exact** value, is it wise to define the number in the database as *float*? This is by definition just an approximate value. Within Ruby, you have arbitrary-precision decimal arithmetic. Maybe you should consider using type :decimal. See also [here](http://stackoverflow.com/questions/8514167/float-vs-decimal-in-activerecord). – user1934428 Mar 17 '16 at 15:01