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 Grosz Mixbook.com

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.

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:

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?

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 Fowler's "Patterns of Enterprise Application Architeture" ( Catalog of Patterns of Enterprise Application Architecture ), there are 3 sections about object-relational mapping tool structure.

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: