Re: Advanced ActiveRecord Question

Sunny Hirai
Sat, 30 Dec 2006 20:25:21 -0000

Hi All,

Thanks for the replies and sorry for the very late response.

I think I might have a solution.

As Rick and Ryan suggested, I like the idea of rewriting the getters and
setters but have them update a hash that is in the encoded_field
attribute. That would solve half the problem.

The other half I could encode the fields into a string before
insert/update with observers and decode the fields from a string back
into a hash during select. Originally I felt that adding new attributes
then converting it to a string in the encoded_field would work (this is
how I do it in my current framework) but it seems that it is simpler to
achieve this by writing new getters/setters for ActiveRecord that set a
hash and then has the hash set the string. Different approach to the
same end.

> This sounds like a bad idea to me. The reason for having a database is
> to avoid doing things like this - you loose your ability to query these
> field. You can design a structure which doesn''t require you add
new
> table columns which would fit this example. For example having a table
> "body_attributes" which may have entries like (1, ''eye
color'') or (2,
> ''has hair'') and then a table called, say,
''body_attribute_values'' with
> entries like (unique_id, 1, "brown") and (unique_id, 2,
"no") where the
> second column is a reference to the id column in
"body_attributes" (you
> could be more complex with the design and allow for
> body_attribute_values of different types other than strings, like
> boolean.)
>
> But if you still want to do it: add a class method to
> ActiveRecord::Base which is this "enocode_fields" method, taking,
as
> you described a hash of default values. For each of those values use
> the ruby function define_method to add methods (like you described) to
> the model.
>
> Ryan

Hi Ryan, I understand your sentiment but in the situation for which I''m
using this, I believe it is the best solution. I used the example of a
"user" because it is easier to explain but it will most often be used
for program settings, layout options, etc.

I do lose "searchability" but on fields that I will never search.

In return, I get

* Better performance (1 db lookup instead of 2 and 1 record returned
instead of several)
* Simplicity (no table joins, no problems with changing an attribute
that has to be checked for existance then doing an insert or update)
* Easy extendibility by extending a prototype (I can add new fields by
adding a key/value to a hash and don''t have to worry about the db. I
can
also remove fields in the same way.)

And if I ever need it, I can still easily refactor to a proper field in
the database.

Thanks also Paul for the suggestion. Actually, I''ve already read that
book but it wasn''t quite enough to solve this issue.

Sunny Hirai
CEO, MeZine Inc.

--
Posted via http://www.ruby-forum.com/.