alias_attribute: handle user defined source methods#52822
Conversation
`alias_attribute` used to define a "jump method", e.g. `alias_attribute :foo, :bar` was pretty much a macro to generate ```ruby def foo bar end ``` This is convienient because it's easy, it doesn't impose an order of declaration or anything like that. But it's also much less efficient than a true `alias_method`. It also used to cause cache size explosion which we fixed in rails#52118, but making it behave like Ruby's `alias_method`, by doing a real alias. But this breaks some expectations (literally from the documentation): ```ruby attr_accessor :name attribute_method_suffix '_short?' define_attribute_methods :name alias_attribute :nickname, :name ``` Here we're not aliasing a generated method, but a user defined one. A solution is to check if the method exist in the class itself, and if it does, alias that user defined method instead of generating one. It solves the issue at hand, but still is more restrictive than the original implementation, as the user method has to be defined before the `alias_attribute` call, but I think that's an OK limitation. Another limitation is that user defined methods have to be defined in the class itself. If they are defined in an ancestor the issue remains.
7c8b520 to
cfccb00
Compare
I think this one is probably fine.
This one might still break some legitimate use cases, which makes me think it could only be shipped in Rails 8.0 per semver. |
|
SemVer isn't the only versioning policy out there, and Rails doesn't follow SemVer. |
Ok, then I misspoke and should have said Rails 7.2.x. |
|
I can probably find a way to handle inheritance too anyway. |
alias_attribute: handle user defined source methods
Fix: #52820
alias_attributeused to define a "jump method", e.g.alias_attribute :foo, :barwas pretty much a macro to generateThis is convienient because it's easy, it doesn't impose an order of declaration or anything like that.
But it's also much less efficient than a true
alias_method.It also used to cause cache size explosion which we fixed in #52118, but making it behave like Ruby's
alias_method, by doing a real alias.But this breaks some expectations (literally from the documentation):
Here we're not aliasing a generated method, but a user defined one.
A solution is to check if the method exist in the class itself, and if it does, alias that user defined method instead of generating one.
It solves the issue at hand, but still is more restrictive than the original implementation, as the user method has to be defined before the
alias_attributecall, but I think that's an OK limitation.Another limitation is that user defined methods have to be defined in the class itself. If they are defined in an ancestor the issue remains.
TODO: write a test, and think of a potential better solution.