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.