# Why don't form helpers read custom model attributes?

**URL:** <https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824>\
**Category:** Rails\
**Created:** [October 27, 2006, 11:47am UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824 "2006-10-27T11:47:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 27, 2006, 11:47am UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/1 "2006-10-27T11:47:41Z")

</div>

Hi!

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 ?

Thanks!

Nicolas.

---

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 27, 2006, 9:21pm UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/2 "2006-10-27T21:21:31Z")

</div>

Nicolas B. wrote:

> Hi!
> 
> 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 ?
> 
> Thanks!
> 
> Nicolas.

The form helpers should be able to read all of the methods on the model.  
My first guess was that the helper was grabbing the date attribute  
instead of your date method, but that doesn’t sound possible to me since  
your method should be triggered first. My second guess is that perhaps  
it won’t use an accessor unless it also has a setter ( ex. a method  
named date=(new\_date) ). Those are just guesses though… if you tried  
creating a differently named method, or adding a setter, it would be  
easy enough to test out.

Tom

---

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 28, 2006, 12:16am UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/3 "2006-10-28T00:16:41Z")

</div>

It always seems to go right to the backend, skipping your code. I run  
into  
this often.

My solution is this:

attr\_writer :date\_for\_form

def date\_for\_form  
read\_attribute(:date).strftime(’%d/%m/%Y’)  
end

before\_validate :copy\_form\_fields

def copy\_form\_fields  
self.attributes(:date) = self.date\_for\_form  
end

Warning: untested. Write a unit test for this before you implement it 🙂

This should allow you to use the form helpers on your new fields  
(date\_for\_form) Kinda kludgy but it will get you going.

---

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 28, 2006, 10:17pm UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/4 "2006-10-28T22:17:57Z")

</div>

Nicolas B. wrote:

> …
> 
> 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  
\_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:📅: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.

---

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 29, 2006, 2:54am UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/5 "2006-10-29T02:54:09Z")

</div>

Mark Reginald J. wrote:

> > end  
> > user input, AR form helpers get their display strings from
> 
> 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

---

<div class="post-metadata">

**Author:** ![budu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b5e925/32.png) [@budu](https://www.ruby-forum.com/u/budu)\
**Post date:** [October 29, 2006, 8:33am UTC](https://www.ruby-forum.com/t/why-dont-form-helpers-read-custom-model-attributes/73824/6 "2006-10-29T08:33:11Z")

</div>

Nicolas B. wrote:

> My problem is that Form helpers like text\_field, text\_area, etc, don’t  
> seem to work with these custom accessors, is that normal ?
> 
> Thanks!
> 
> Nicolas.

Nicolas,

Yes, this is normal. And for whatever it’s worth, I’ve learned and  
forgotten this at least 3 times - since I’m thinking in pure OO mode  
most of the time and I expect overridden methods to get called.

Because you can do complex transformations in a custom attribute reader,  
Rails gets the attribute value using \_before\_type\_cast.

One way to think about the reason for this is because Rails has no  
built-in notion of a model of the form’s state (what in the J2EE world  
might be called a “form bean”). Because the default behavior of the  
ActiveRecord/controller/view interaction is to read/write attributes  
directly from the DB to/from the view, there’s no facility to keep track  
of what’s going on the form during unsuccessful attempts to save a  
particular attribute (e.g. what was typed into the form field when it’s  
not valid).

In effect, you end up using a custom attribute reader/writer pair to  
manage this form state. If you take the set of all such methods that  
you end up writing on your ActiveRecord object, you would see that they  
basically represent a “form state” or “form model” object, even though  
they are methods on the model.

I’ve been thinking about this a lot. Take a look at the ActiveForm  
plugin for one way to formalize this “form model” notion. In cases  
where the form state can be complex, a separate form model would keep  
your form state straight, but then would imply a copying step from the  
form model attributes into the model attributes and the opposite.

If most of your model attributes don’t need tweaking to be displayed,  
then just adding a couple of custom attribute reader/writer pairs is  
probably sufficient.

But I think it’s helpful to keep the distinction between form data  
concerns and model data concerns in mind.

Wes
