ActiveRecord and Form Data Coupling: A Bad Design

I have to say that after being a Rails user for some time I have grown
to really dislike how ActiveRecord (AR) classes - models - are being
pushed as the defacto method for getting form data into the DB. The
two concepts are completely separate and should be handled by
completely different classes.

Anyone who understands Object Oriented Design knows that we separate
classes based on functionality and responsibility. An automobile
class, for example, would represent something that has wheels and
drives; a fixed-wing aircraft class would represent something that
flies. Such is the case with AR, it handles the interaction with the
database and holds the data, and perhaps has some extra methods that
interact with the data it holds. Also, what we see a lot of is having
the AR class also handle data coming from a form, which breaks
encapsulation. It’s like saying that to build the ultimate vehicle
would be to put wings on a car because it would be get us in a jiffy
whether we had to go short or long distances (a nice idea, but try
driving down Broadway with wings spanning forty feet).

The problem with coupling the form and the AR is that it may have very
little resemblance to the form that is creating it. I’ve encountered
this quite a bit. For registration (user model) I had to add a number
of attributes to the class that had no mapping to the db, that hung
around and cluttered up the design tremendously. Furthermore, the
need to have those attributes validated compounded the problem further
since some could only be validated on create or on update. Also
whenever I wanted to save the object when not in form mode i always
needed extra code to flag or message the object so that it wouldn’t
validate itself - a time consuming and unnecessary task.

The ultimate solution was to do what OOD says to do - break out the
forms into a completely separate class that handled and validated the
form data and then passed the data to the AR object. Needless to say,
it took quite a bit of time to do, and I think it’s the best
solution. I hope that the next versions of Rails will contain some
kind of ActiveForm class for the sake of others.

On 10/14/07, ProfKheel [email protected] wrote:

drives; a fixed-wing aircraft class would represent something that
little resemblance to the form that is creating it. I’ve encountered
forms into a completely separate class that handled and validated the
form data and then passed the data to the AR object. Needless to say,
it took quite a bit of time to do, and I think it’s the best
solution. I hope that the next versions of Rails will contain some
kind of ActiveForm class for the sake of others.

I’m sure we’ve all run into this at one point or another for
non-trivial forms. But, this kind of radical change is best served as
a plugin to start. Share your active_form plugin with the world and
prove with real code in production that it kicks ass.

One thing I would like to do, for start, is extract some of the common
‘model’ code out of ActiveRecord into some kind of ActiveModel class.
This includes basic validation functionality, as well as callbacks
possibly. It’s something I may look into later after Rails 2.0 has
been released.


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

On 10/13/07, ProfKheel [email protected] wrote:

drives; a fixed-wing aircraft class would represent something that
little resemblance to the form that is creating it. I’ve encountered
forms into a completely separate class that handled and validated the
form data and then passed the data to the AR object. Needless to say,
it took quite a bit of time to do, and I think it’s the best
solution. I hope that the next versions of Rails will contain some
kind of ActiveForm class for the sake of others.

You might find the Presenter pattern useful:

Pat

On Oct 13, 2007, at 10:40 PM, Rick O. wrote:

classes based on functionality and responsibility. An automobile
driving down Broadway with wings spanning forty feet).
since some could only be validated on create or on update. Also
kind of ActiveForm class for the sake of others.
been released.
The current design seems “natural” to me because 9x of 10 it’s what
you want. Form data goes into table either verbatim or with few
manipulations. But for that 1x, it’s a pain.

I’ve used my own framework for several years now which had validation
coupled to the form-to-table process as well. I also started to get
more annoyed when I needed things just a hair outside the norm. Quite
recently, I finally decoupled the validation process and forma data
storage as you’re suggesting so I could accept and validate forms w/o
being forced to map that onto a table at that instant. However, I did
it in a way that the ORM and validation system did have intimate
enough knowledge to still provide that automatic magic with virtually
no effort. While that may also be imperfect OOD, it seemed the right
thing to do to preserve the magic, yet not be hostage to it as well.

Vague, I know, but just saying that I think a design compromise is
both possible and worthwhile.

– gw