Why don't form helpers read custom model attributes ?

Nicolas Blanco wrote:

I'm using custom read and write accessors in my models like :

class Order < ActiveRecord::Base

...

def date   read_attribute(:date).strftime('%d/%m/%Y') end

...

end

My problem is that Form helpers like text_field, text_area, etc, don't seem to work with these custom accessors, is that normal ?

In order to preserve both database field formats and redisplayed user input, AR form helpers get their display strings from <attribute>_before_type_cast methods.

So you could write:

def date_before_type_cast    date.strftime('%d/%m/%Y') end

But if you want a common date display format throughout your app, instead add

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS[:default] = '%d/%m/%Y'

to environment.rb, and write in your model

def date_before_type_cast    date.to_s end

You'll also need a setter

def date=(val)    self[:date] = val.is_a?(String) ? val.to_date : val end

plus, since Rails does not currently support non-US formats for string-to-date conversions, you'll have to add this to environment.rb

class String    def to_date      Date.strptime(self, '%d/%m/%Y')    end end

Mark Reginald James wrote:

Nicolas Blanco wrote:

> I'm using custom read and write accessors in my models like : > > class Order < ActiveRecord::Base > > ... > > def date > read_attribute(:date).strftime('%d/%m/%Y') > end > > ... > > end > > My problem is that Form helpers like text_field, text_area, etc, don't > seem to work with these custom accessors, is that normal ?

In order to preserve both database field formats and redisplayed user input, AR form helpers get their display strings from <attribute>_before_type_cast methods.

So you could write:

def date_before_type_cast    date.strftime('%d/%m/%Y') end

But if you want a common date display format throughout your app, instead add

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS[:default] = '%d/%m/%Y'

to environment.rb, and write in your model

def date_before_type_cast    date.to_s end

You'll also need a setter

def date=(val)    self[:date] = val.is_a?(String) ? val.to_date : val end

plus, since Rails does not currently support non-US formats for string-to-date conversions, you'll have to add this to environment.rb

class String    def to_date      Date.strptime(self, '%d/%m/%Y')    end end

-- We develop, watch us RoR, in numbers too big to ignore.

I strongly recommend that you DO NOT CHANGE THE DEFAULT DATE FORMAT. This will lead to unending pain and suffering, and will highly displease the gods of MySQL.

If you change the default date format, rails will use this format to try and write dates to the db. Mostl likely this will result in a silent failure (at least in MySQL). Your dates will just get recorded as '0000-00-00', and you will lose fistfuls of hair trying to figure out why.

See tickets #6019 and #6363

_Kevin