Parameters not getting saved in Rails 3 app -


i rails 3 beginner working on application allows user enter monetary values. using jquery plugin (http://github.com/plentz/jquery-maskmoney) display decimal values monetary values on edit page. decimal attributes manipulated currency when editing. when saving the, purchase_price , capital_reserves saved correctly. property before_save function called , currency values ($123.45) converted decimal values (123.45).

the problem associated rent values never saved if edit rent prices. can see correct values being sent in parameters before_save code in rent model never triggered. if edit apartment number value , rent price, rent price saved correctly. also, after can edit price apartment number modified. however, other rent price not updated.

i using mysql , rails 3.0.9

steps reproduce: non-issue

  1. edit property
  2. modify property's purchase price and/or capital reserves value
  3. click update
  4. these values converted currency values ($1,234.56) decimal (1234.56) before_save code in property

issue

  1. edit property
  2. modify property's rent current price and/or market price values
  3. click update
  4. these values not saved. before_save code not called in rent model.

issue

  1. edit property
  2. modify property's purchase price and/or capital reserves value, edit apartment number
  3. click update
  4. these values saved correctly.
  5. now can edit price values row saved , prices saved. why?

i made small project showcase if interested (https://github.com/michaelklem/money-test).

here data models.

property class

class property < activerecord::base   before_save :handle_before_save   has_many :rents, :dependent => :destroy   accepts_nested_attributes_for :rents, :allow_destroy => true    def handle_before_save     if new_record?       generate_default_rent_data     end      remove_currency_formatting   end    def generate_default_rent_data     10.times |i|       self.rents.build(:apartment_number => i+1)     end   end    def remove_currency_formatting         if self.capital_reserves.to_s != self.capital_reserves_before_type_cast.to_s       self.capital_reserves = property.remove_currency_format(self.capital_reserves_before_type_cast)      end       if self.purchase_price.to_s != self.purchase_price_before_type_cast.to_s        self.purchase_price = property.remove_currency_format(self.purchase_price_before_type_cast)      end   end    #   # handles removing characters currency objects   # except 0-9 , .   #   def self.remove_currency_format(currency_attribute)     currency_attribute.gsub(/[^0-9.]/, "")   end end 

rent class:

class rent < activerecord::base   belongs_to :property   before_save :handle_before_save    def handle_before_save     remove_currency_formatting   end    def remove_currency_formatting         if self.current_price.to_s != self.current_price_before_type_cast.to_s       self.current_price = property.remove_currency_format(self.current_price_before_type_cast)      end       if self.market_price.to_s != self.market_price_before_type_cast.to_s        self.market_price = property.remove_currency_format(self.market_price_before_type_cast)      end   end  end 

not sure if seeing bug or missing obvious. looking this.

update

after posted found question stripping first character of string helped me figure out. still seems me original issue bug.

i able simplify code following , works.

class property < activerecord::base    before_save :handle_before_save    has_many :rents, :dependent => :destroy   accepts_nested_attributes_for :rents, :allow_destroy => true    def handle_before_save     if new_record?       generate_default_rent_data     end   end    def purchase_price=(data)       if data.is_a?(string)         data = property.remove_currency_format(data)         write_attribute(:purchase_price, data)       end   end    def capital_reserves=(data)       if data.is_a?(string)         data = property.remove_currency_format(data)         write_attribute(:capital_reserves, data)       end   end    #   # generate default data   #   def generate_default_rent_data     10.times |i|       self.rents.build(:apartment_number => i+1) # provide default value apartment numbers     end   end    def self.remove_currency_formatting(data)     if data.is_a?(string)       data = property.remove_currency_format(data)     end     return data   end    #   # handles removing characters currency objects   # except 0-9 , .   #   def self.remove_currency_format(currency_attribute)     currency_attribute.gsub(/[^0-9.]/, "")   end    def purchase_price=(data)       _write_attribute(:purchase_price, data)   end    def capital_reserves=(data)       _write_attribute(:capital_reserves, data)   end    private    def _write_attribute(attribute, data)     write_attribute(attribute, property.remove_currency_formatting(data))   end  end   class rent < activerecord::base   belongs_to :property    def current_price=(data)     _write_attribute(:current_price, data)   end    def market_price=(data)       _write_attribute(:market_price, data)   end    private    def _write_attribute(attribute, data)     write_attribute(attribute, property.remove_currency_formatting(data))   end end 

this may helpful, , might clean lot of write_attribute code if chose use it.

in our app, run issue frequently, have tons of amount fields , hellish add logic each model (almost every table has decimal fields amounts). in initializer, added following:

activerecord::connectionadapters::column.class_eval    def type_cast_with_commas_removed(value)     if type == :decimal && value.is_a?(string)       value = value.delete(',')     end     type_cast_without_commas_removed(value)   end    alias_method_chain :type_cast, :commas_removed  end  class bigdecimal   alias :old_to_s :to_s    def to_s(s=nil)     if s.nil?       parts = ("%.2f" % self).split('.')       parts[0].gsub!(/(\d)(?=(\d{3})+(?!\d))/, "\\1,")       parts.join('.')     else       old_to_s(s)     end   end  end 

this achieves 2 things: first, on insertion database, commas stripped decimal field entries if value string (you change use regex of grabbing numbers , period). second, when bigdecimal converted string commas re-inserted (this business requirement in our case wanted display proper formatting @ times, may not need).

anyway, know solved problem, wanted give approach. :)

cheers!


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -