Ruby on Rails
Thursday, April 24, 2014
FWIW, no, it is not possible to do that without a LOT of sanitation of Rails/ActiveRecord code.
The problem is that the <extremely competent and forward-looking> developers decided to do all the heavy lifting in reflections instead of the associations. Why is that a problem? Because reflections *have no information AT ALL* about the specific association they are being used for.
Example: you have a model "Dog" that has_many :bones.
Now: dog = Dog.first; dog.bones #=> Array
Ignore the "Array" part, that's due to idiocy of the framework (basically AssociationProxy tries to be a BasicObject and fails *hard*). The framework at that point does the actual lookup through an "association proxy" which has a lot of information: the specific dog, ultimately all the bones, and additionally the reflection which has all information about the "has_many" call. Rails then goes on to basically throw away all the nice information from the association proxy, turns to the reflection, and ends up with two methods: Reflection#class_name and the derived #class_name, both of which boil down to either a value derived from the association name itself, or the :class_name option.
Now you might think, alright, I'll just do some minimal hacking and fix stuff so Reflection#class_name looks up the "left side" of the association call. That won't work, because (1) the reflection is really just a dumb memoisation of the has_many call, and (2) it's pretty much a singleton, so if you change it, you'll break your entire runtime.
You might also think that you could fix up the AssociationProxy. That's a better thought since it konws about the owner model and can just call aribtrary methods in there, but then you spend 4 hours on it, just to realise that later on the framework decides to use Reflection#chain and effectively bypasses all your fancy work when trying to build the scope for the final query.
All in all, it's another case of Rails/AR being a humongous pile of <organically-grown code> that is pretty much unadaptable to your fancy concepts unless you want to sit down and rewrite large parts of it.
-- The problem is that the <extremely competent and forward-looking> developers decided to do all the heavy lifting in reflections instead of the associations. Why is that a problem? Because reflections *have no information AT ALL* about the specific association they are being used for.
Example: you have a model "Dog" that has_many :bones.
Now: dog = Dog.first; dog.bones #=> Array
Ignore the "Array" part, that's due to idiocy of the framework (basically AssociationProxy tries to be a BasicObject and fails *hard*). The framework at that point does the actual lookup through an "association proxy" which has a lot of information: the specific dog, ultimately all the bones, and additionally the reflection which has all information about the "has_many" call. Rails then goes on to basically throw away all the nice information from the association proxy, turns to the reflection, and ends up with two methods: Reflection#class_name and the derived #class_name, both of which boil down to either a value derived from the association name itself, or the :class_name option.
Now you might think, alright, I'll just do some minimal hacking and fix stuff so Reflection#class_name looks up the "left side" of the association call. That won't work, because (1) the reflection is really just a dumb memoisation of the has_many call, and (2) it's pretty much a singleton, so if you change it, you'll break your entire runtime.
You might also think that you could fix up the AssociationProxy. That's a better thought since it konws about the owner model and can just call aribtrary methods in there, but then you spend 4 hours on it, just to realise that later on the framework decides to use Reflection#chain and effectively bypasses all your fancy work when trying to build the scope for the final query.
All in all, it's another case of Rails/AR being a humongous pile of <organically-grown code> that is pretty much unadaptable to your fancy concepts unless you want to sit down and rewrite large parts of it.
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/8c7e2aa5-eeca-4469-9e22-6af7280a65cf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment