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?
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.
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?
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.
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.