We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
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.
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.