Rails 6 adds private option to delegate method

Amit Choudhary

By Amit Choudhary

on June 10, 2019

This blog is part of our  Rails 6 series.

Rails 6 adds :private option to delegate method. After this addition, we can delegate methods in the private scope.

Let's checkout how it works.

Rails 6.0.0.beta2

Let's create two models named as Address and Order. Let's also delegate validate_state method in Order to Address.

1class Address < ApplicationRecord
2  validates :first_name, :last_name, :state, presence: true
3
4  DELIVERABLE_STATES = ['New York']
5
6  def validate_state
7    unless DELIVERABLE_STATES.include?(state)
8      errors.add(:state, :invalid)
9    end
10  end
11end
12
13class Order < ApplicationRecord
14  belongs_to :address
15
16  delegate :validate_state, to: :address
17end
18
19>> Order.first
20SELECT "orders".* FROM "orders"
21ORDER BY "orders"."id" ASC LIMIT $1  [["LIMIT", 1]]
22
23=> #<Order id: 1, amount: 0.1e2, address_id: 1, created_at: "2019-03-21 10:02:58", updated_at: "2019-03-21 10:17:44">
24
25>> Address.first
26SELECT "addresses".* FROM "addresses"
27ORDER BY "addresses"."id" ASC LIMIT $1  [["LIMIT", 1]]
28
29=> #<Address id: 1, first_name: "Amit", last_name: "Choudhary", state: "California", created_at: "2019-03-21 10:02:47", updated_at: "2019-03-21 10:02:47">
30
31>> Order.first.validate_state
32SELECT "orders".* FROM "orders"
33ORDER BY "orders"."id" ASC LIMIT $1  [["LIMIT", 1]]
34
35SELECT "addresses".* FROM "addresses"
36WHERE "addresses"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
37
38=> ["is invalid"]

Now, let's add private: true to the delegation.

1class Order < ApplicationRecord
2  belongs_to :address
3
4  delegate :validate_state, to: :address, private: true
5end
6
7>> Order.first.validate_state
8SELECT "orders".* FROM "orders"
9ORDER BY "orders"."id" ASC LIMIT $1  [["LIMIT", 1]]
10
11=> Traceback (most recent call last):
12        1: from (irb):7
13NoMethodError (private method 'validate_state' called for #<Order:0x00007fb9d72fc1f8>
14Did you mean?  validate)

As we can see, Rails now raises an exception of private method called if private option is set with delegate method.

Here is the relevant pull request.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.