Rails 6 ActiveSupport adds private option to delegated methods

Rails 6 is recently released with a lot of features. One of them is ActiveSupport adding support for private option on delegated methods to make delegated methods not accessible publicly.

Before Rails 6

Before Rails 6, if we use delegate option for methods, it marks the delegated method publicly accessible. This could be undesirable at times if we need the delegated method to be a private method.

class User
  has_one :profile

  delegate :date_of_birth, to: :profile
end

Now, we can call date_of_birth on an instance of User model as given below.

user = User.first
# => #<User id: 1, email: "akshayymohite@gmail.com", created_at: "2019-07-23 10:01:34", updated_at: "2019-08-21 06:32:57", first_name: "Akshay", last_name: "Mohite", friendly_name: "Akshay Mohite">

user.date_of_birth
# => 29

Thus, there was no way to make delegated methods private before Rails 6.

After Rails 6

This pull request introduces private option for the delegated methods. We can make a certain method as a private method by using this modifier as given below.

class User
  has_one :profile

  delegate :date_of_birth, to: :profile, private: true
end

As we can see, we have passed

private: true

To the delegate call.

Now, if we call date_of_birth method on an instance of User, it will raise a NoMethodError saying, private method date_of_birth called for user object.

NoMethodError (private method `date_of_birth' called for #<User:0x00007ff2487906c0>)

It will be available to methods available on an instance of user as given below.

class User
  has_one :profile

  delegate :date_of_birth, to: :profile, private: true

  def age
    Date.today.year - date_of_birth.year
  end
end

Now, if we call age, it will be able to call private method date_of_birth and return desired result.

Leave a Comment

Your email address will not be published. Required fields are marked *