Aliasing the Ruby & Rails way

Christian Rolle
2 min readFeb 15, 2023

--

A method alias can make sense or even can be necessary for various reasons.

  1. Satisfy TemplateMethod requirements using duck typing
  2. Increasing a methods meaning/ readability
  3. Extend a methods behavior (in the sense of aspect oriented programming)

Since there are 2 ways of aliasing in Rails I’m going to disclose both and when to use which one.
Let’s start with the alias_method.

Pure Ruby aliasing

Consider a PORO like Article.

class Article
attr_reader :name
alias_method :topic, :name

def initialize(name)
@name = name
end
end

and use it accordingly:

article = Article.new('Ruby')
article.name
# => "Ruby"
article.topic
# => "Ruby"

Simple as that.
However with Rails models we have to respect how Rails model work.

Rails model aliasing

First we try to apply the Ruby aliasing to Rails models as well.

rails g model Article name:string && rake db:migrate

and the corresponding model with an alias topic on the attribute method name:

class Article < ApplicationRecord
alias_method :topic, :name
end

Unfortunately that does not work.

Article.new
# => NameError: undefined method `name' for class 'Article'

The reason is how Rails model work internally. Ruby on Rails creates attribute accessors dynamically and therefore helps itself with meta programming and the method_missing approach. But at the time of class instantiation the accessors are not created yet.

However when alias_method tries to make a copy of the original method, it consequentially fails withNameError.

The solution is Module#alias_attribute. Ruby on Rails extended Module and enables aliasing in ActiveRecord. The principle is simple. A new method is created by meta programming, which internally calls the original method.

Thus the model has to look like:

class Article < ApplicationRecord
alias_attribute :topic, :name
end

with:

article = Article.new(name: 'Ruby')
article.name
# => "Ruby"
article.label
# => "Ruby"

Furthermore alias_attribute generates the appropriate setter methods.

article = Article.new(name: 'Ruby')
article.topic = 'RubyOnRails'
article.name
# => "RubyOnRails"
article.topic
# => "RubyOnRails"

Since the alias_attribute is glued toModule, it works for each class even POROs:

class Book
attr_accessor :name
alias_attribute :title, :name

def initialize(name:)
@name = name
end
end

With that Book provides two more methods label and label=

book = Book.new name: 'Ruby'
book.title
# => "Ruby"
book.title = 'RubyOnRails'
book.title
# => "RubyOnRails"
book.name
# => "RubyOnRails"

Resources

--

--

Christian Rolle
Christian Rolle

Written by Christian Rolle

#Ruby on Rails full stack web developer in the enterprise business with a passion for people. I am constantly blogging.

No responses yet