BigBinary Blog

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

Rails 6 adds private option to delegate method

This blog is part of our Rails 6 series.

Rails 6.0 was recently released.

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.

Amit Choudhary in Rails 6
June 10, 2019
Share

Subscribe to our newsletter