Polymorphic Associations in Rails 2 not configurable

This has been bugging me for some time.

The implementation for polymorphic associations in Rails is still
using the record_type, record_id model where record type has to be the
entire written out class name.

All of this logic is hardcoded deep in ActiveRecord, making it very
difficult to deviate from this.

For example, what if I wanted to have the “type” column be a tinyint
unsigned that mapped with the name of the class in some hash? Or what if
I wanted to infer the type from a different column all together?

Repeating a long classname for every row in a database is repetitive and
can eat up database size. For example, “SomeLongModuleName::ModelName”
could be replaced with “1”, which would then map to that name. That
would be 1 byte for the TinyInt(3) implementation vs N bytes for
actually spelling out the class name every time.

Whats frustrating me is the inability to easily configure this, or even
to patch this to get it to work properly. Is anyone also having issues
with this or is there anything out there to give you more control over
polymorphic associations?

Aryk G.

You could just build your own associations solution instead of trying to
patch the polymorphic associations.

Also, if you have indexes for the columns, the time “searching” for the
row
isn’t really different than it would be for a number instead of a
varchar.
The database should hit the result row in the same time.

On Tue, Oct 7, 2008 at 11:07 PM, Aryk G. <
[email protected]> wrote:

For example, what if I wanted to have the “type” column be a tinyint
to patch this to get it to work properly. Is anyone also having issues
with this or is there anything out there to give you more control over
polymorphic associations?

Aryk G.
Mixbook.com

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


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208

Yes you could just build your own for this task or that task, but then
you start adding function after function until you realize why
activerecord made associations in the first place (getters, setters,
callbacks, reflections). =)

I tried patching polymorphic associations, its not easy, because you
have to change the behavior in like 10 different places. Its not pretty.

Im not worried about the time searching for the record, Im frustrated
about using 30 bytes to store “ThisLongClassNameBlahBlah” vs 1 byte to
store a number that maps to that name for every record.

Also, I’d have to add a “_type” column even though you could infer the
classname based off another column, thus making things anything but DRY.

Maurício Linhares wrote:

You could just build your own associations solution instead of trying to
patch the polymorphic associations.

Also, if you have indexes for the columns, the time “searching” for the
row
isn’t really different than it would be for a number instead of a
varchar.
The database should hit the result row in the same time.

On Tue, Oct 7, 2008 at 11:07 PM, Aryk G. <
[email protected]> wrote:

For example, what if I wanted to have the “type” column be a tinyint
to patch this to get it to work properly. Is anyone also having issues
with this or is there anything out there to give you more control over
polymorphic associations?

Aryk G.
Mixbook.com

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


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208

On Tue, Oct 7, 2008 at 11:38 PM, Aryk G. <
[email protected]> wrote:

Also, I’d have to add a “_type” column even though you could infer the
classname based off another column, thus making things anything but DRY.

Could you explain this a little bit more?

I guess i don’t get the idea you’re trying to reach here. How could you
infer the classname based on another column without having the classname
in
that other column?


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208

Well, that’s definitely a “complicated” example :slight_smile:

I guess you should try to figure out with the core rails guys where
you could hack the code to do just that (what would be infer the name
of the real association from something else), i haven’t looked at the
code myself, but it shouldn’t be that hard with the right guidance.

Also, if you want to roll your own solution, it isn’t that hard and
there’s also plenty of work already written about the matter, one of
the best options is Martin F.'s “Patterns of Enterprise
Application Architeture” (
Catalog of Patterns of Enterprise Application Architecture ), there are 3 sections
about object-relational mapping tool structure.

On Wed, Oct 8, 2008 at 1:30 AM, Aryk G.
[email protected] wrote:

So, now I need a “detail_type” column of “BookDetail” or in other words
“#{product_type.classify}Detail”.

Now I have two extra string columns that are not needed and are making
things much less DRY.

Aryk


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208

Thanks for the input,

I wouldnt say this is exactly a complicated example. Its basically where
you could infer the polymorphic class from STI type sort of thing. Im
pretty sure many other people run into it.

The bottom line is that there is no customizablility.

The problem is that the code has sql strings generated with
"#{variable}_type = X which makes it very hard to replace with a
function to control the outputted polymorphic sql condition.

I wonder if there is anybody else that has run into the same problems.

Maurício Linhares wrote:

Well, that’s definitely a “complicated” example :slight_smile:

I guess you should try to figure out with the core rails guys where
you could hack the code to do just that (what would be infer the name
of the real association from something else), i haven’t looked at the
code myself, but it shouldn’t be that hard with the right guidance.

Also, if you want to roll your own solution, it isn’t that hard and
there’s also plenty of work already written about the matter, one of
the best options is Martin F.'s “Patterns of Enterprise
Application Architeture” (
Catalog of Patterns of Enterprise Application Architecture ), there are 3 sections
about object-relational mapping tool structure.

On Wed, Oct 8, 2008 at 1:30 AM, Aryk G.
[email protected] wrote:

So, now I need a “detail_type” column of “BookDetail” or in other words
“#{product_type.classify}Detail”.

Now I have two extra string columns that are not needed and are making
things much less DRY.

Aryk


Maur�cio Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
Jo�o Pessoa, PB, +55 83 8867-7208

Sure Mauricio, here’s an example.

Lets say you have a “products” table. You have product_type table column
in that table that you use for single table inheritance. So lets say you
have the value “book” as the product_type.

Now you want to have a pricing for this product, so you do:

belongs_to :pricing, :polymorphic => true

So now you need a pricing_type with a class name of “BookPricing”, or in
other words “#{product_type.classify}Pricing”. You will always follow
this convention since I wouldnt have BookPricing for a product_type of
“poster”

But wait! There’s more. Now I want another polymorphic association for
“details” for that product. So I do:

belongs_to :detail, :polymorphic => true

So, now I need a “detail_type” column of “BookDetail” or in other words
“#{product_type.classify}Detail”.

Now I have two extra string columns that are not needed and are making
things much less DRY.

Aryk

Maurício Linhares wrote:

On Tue, Oct 7, 2008 at 11:38 PM, Aryk G. <
[email protected]> wrote:

Also, I’d have to add a “_type” column even though you could infer the
classname based off another column, thus making things anything but DRY.

Could you explain this a little bit more?

I guess i don’t get the idea you’re trying to reach here. How could you
infer the classname based on another column without having the classname
in
that other column?


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208