Frank Mattia
2012-Oct-29 23:57 UTC
Saving values to the db as metric but displaying/editing in imperial.
I have a requirement to store values in a database as unitless decimals(12,9) which will be presumed to be metric values. For display/editing purposes I need the user to be able to choose their input method -- no mixing and matching on a form, just a simple User#current_units call to determine the expected units. For example. item: name: item1 diameter: 150 width: 6 When User#current_units is "mm" all of my form fields are straight forward... f.label "Diameter" f.text_field :diameter My issue is when a current_units is "in", what''s a good method for doing all the translation? The text_field for diameter should read "5.9055". If a user altered it to read "6" then it should save back to the db as "152.400000000" I''ve tried everything from the ruby-units gem to composed_of (which is practically useless with rails 4 getting rid of it). storing the units in the db is a no go only because I need to be able to search for "items where diameter > x and diameter < y" If anyone has any theories on a good starting point I''d love to elaborate further on what I''ve tried and failed with. Thanks, - FJM -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/G0EjqYKGLYMJ. For more options, visit https://groups.google.com/groups/opt_out.
Scott Ribe
2012-Oct-30 00:23 UTC
Re: Saving values to the db as metric but displaying/editing in imperial.
Unless I''m missing something, you want a setter and getter for a "virtual" attribute: say DiameterStr and DiameterStr=, which perform or not the conversion as needed. Then you always reference f.text_field :DiameterStr. You could always play around with making the underlying attributes private, or at least a diameter= method which throws an exception... (Which slightly complicates DiameterStr=...) On Oct 29, 2012, at 5:57 PM, Frank Mattia wrote:> If anyone has any theories on a good starting point I''d love to elaborate further on what I''ve tried and failed with. >-- Scott Ribe scott_ribe-ZCQMRMivIIdUL8GK/JU1Wg@public.gmane.org http://www.elevated-dev.com/ (303) 722-0567 voice -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/groups/opt_out.
Frank Mattia
2012-Nov-01 19:48 UTC
Re: Saving values to the db as metric but displaying/editing in imperial.
Thanks Scott, I''m closer but not quite there. I had originally tried virtual attributes but all my implementations fell short. After you suggested it, I did some more homework and tried again. Now I have a solution that works in every way except validation. My virtual attributes are defined like this: def diameter_in_units> Unit.to_current(read_attribute(:diameter)) > end >> def diameter_in_units=(value) > write_attribute(:diameter, Unit.to_db(value)) > end#to_current and #to_db just apply a conversion factor depending on the users current_units setting but my issue is visible when the user errantly inputs something that isn''t a number, it never triggers my validations. I''m not 100% but I believe it is because the #to_ methods are coercing the string input to a BigDecimal before doing any calculation and therefore if the user inputs a string it helpfully changes it to zero for the calculation. 1.9.3p194 :036 > "randomstring".to_d.to_s> => "0.0"How can I get around this without duplicating validation code while still getting the full "validation experience"? Thanks for your advice, - FJM On Monday, October 29, 2012 8:24:19 PM UTC-4, Scott Ribe wrote:> > Unless I''m missing something, you want a setter and getter for a "virtual" > attribute: say DiameterStr and DiameterStr=, which perform or not the > conversion as needed. Then you always reference f.text_field :DiameterStr. > > You could always play around with making the underlying attributes > private, or at least a diameter= method which throws an exception... (Which > slightly complicates DiameterStr=...) > > On Oct 29, 2012, at 5:57 PM, Frank Mattia wrote: > > > If anyone has any theories on a good starting point I''d love to > elaborate further on what I''ve tried and failed with. > > > > > -- > Scott Ribe > scott...-ZCQMRMivIIdUL8GK/JU1Wg@public.gmane.org <javascript:> > http://www.elevated-dev.com/ > (303) 722-0567 voice > > > > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/0w2DUPvij2MJ. For more options, visit https://groups.google.com/groups/opt_out.
Frank Mattia
2012-Nov-01 23:52 UTC
Re: [SOLVED] Saving values to the db as metric but displaying/editing in imperial.
In case anyone ever wants to do something similar and runs into the same follies I''ll leave my solution here: Model> class Thing < ActiveRecord::Base > attr_accessible :diameter_in_unitsvalidates :diameter_in_units, numericality: true> > before_save :update_diameter_in_units, if: :diameter_changed?> def diameter_in_units > @diameter_in_units || Unit.to_current(read_attribute(:diameter)) > end> def diameter_in_units=(value) > diameter_will_change! > @diameter_in_units = value > end > > private > def update_diameter_in_units > write_attribute(:diameter, Unit.to_db(diameter_in_units)) > end > endOn Thursday, November 1, 2012 3:48:55 PM UTC-4, Frank Mattia wrote:> Thanks Scott, > > I''m closer but not quite there. I had originally tried virtual attributes > but all my implementations fell short. After you suggested it, I did some > more homework and tried again. Now I have a solution that works in every > way except validation. My virtual attributes are defined like this: > > def diameter_in_units >> Unit.to_current(read_attribute(:diameter)) >> end >> > >> def diameter_in_units=(value) >> write_attribute(:diameter, Unit.to_db(value)) >> end > > > #to_current and #to_db just apply a conversion factor depending on the > users current_units setting but my issue is visible when the user errantly > inputs something that isn''t a number, it never triggers my validations. I''m > not 100% but I believe it is because the #to_ methods are coercing the > string input to a BigDecimal before doing any calculation and therefore if > the user inputs a string it helpfully changes it to zero for the > calculation. > > 1.9.3p194 :036 > "randomstring".to_d.to_s >> => "0.0" > > > How can I get around this without duplicating validation code while still > getting the full "validation experience"? > > Thanks for your advice, > - FJM > > On Monday, October 29, 2012 8:24:19 PM UTC-4, Scott Ribe wrote: >> >> Unless I''m missing something, you want a setter and getter for a >> "virtual" attribute: say DiameterStr and DiameterStr=, which perform or not >> the conversion as needed. Then you always reference f.text_field >> :DiameterStr. >> >> You could always play around with making the underlying attributes >> private, or at least a diameter= method which throws an exception... (Which >> slightly complicates DiameterStr=...) >> >> On Oct 29, 2012, at 5:57 PM, Frank Mattia wrote: >> >> > If anyone has any theories on a good starting point I''d love to >> elaborate further on what I''ve tried and failed with. >> > >> >> >> -- >> Scott Ribe >> scott...-ZCQMRMivIIdUL8GK/JU1Wg@public.gmane.org >> http://www.elevated-dev.com/ >> (303) 722-0567 voice >> >> >> >> >>-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/5ztrCgsqjNwJ. For more options, visit https://groups.google.com/groups/opt_out.
Scott Ribe
2012-Nov-02 02:33 UTC
Re: [SOLVED] Saving values to the db as metric but displaying/editing in imperial.
On Nov 1, 2012, at 5:52 PM, Frank Mattia wrote:> In case anyone ever wants to do something similar and runs into the same follies I''ll leave my solution here:I never saw your second question; but I like your solution and will use it ;-) -- Scott Ribe scott_ribe-ZCQMRMivIIdUL8GK/JU1Wg@public.gmane.org http://www.elevated-dev.com/ (303) 722-0567 voice -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/groups/opt_out.