Skip to content

alias_attribute: handle user defined source methods#52822

Merged
byroot merged 1 commit intorails:mainfrom
byroot:active-model-alias
Sep 9, 2024
Merged

alias_attribute: handle user defined source methods#52822
byroot merged 1 commit intorails:mainfrom
byroot:active-model-alias

Conversation

@byroot
Copy link
Member

@byroot byroot commented Sep 6, 2024

Fix: #52820

alias_attribute used to define a "jump method", e.g. alias_attribute :foo, :bar was pretty much a macro to generate

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 #52118, but making it behave like Ruby's alias_method, by doing a real alias.

But this breaks some expectations (literally from the documentation):

  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.

TODO: write a test, and think of a potential better solution.

`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.
@byroot byroot force-pushed the active-model-alias branch from 7c8b520 to cfccb00 Compare September 6, 2024 18:56
@benlangfeld
Copy link

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.

I think this one is probably fine.

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.

This one might still break some legitimate use cases, which makes me think it could only be shipped in Rails 8.0 per semver.

@byroot
Copy link
Member Author

byroot commented Sep 6, 2024

SemVer isn't the only versioning policy out there, and Rails doesn't follow SemVer.

@benlangfeld
Copy link

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.

@byroot
Copy link
Member Author

byroot commented Sep 6, 2024

I can probably find a way to handle inheritance too anyway.

@byroot byroot merged commit b2567ea into rails:main Sep 9, 2024
@byroot byroot deleted the active-model-alias branch September 9, 2024 10:16
byroot added a commit that referenced this pull request Sep 9, 2024
alias_attribute: handle user defined source methods
byroot added a commit that referenced this pull request Sep 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

alias_attribute broken in Rails 7.1.4

2 participants