9

An example of Rails controller which defines a private method:

class ApplicationController < ActionController::Base
  private
  def authorization_method
    # do something
  end
end

Then, it's being used in a subclass of ApplicationController:

class CustomerController < ApplicatioController
  before_action :authorization_method

  # controller actions
end

How is it possible that a private method is called from its subclass? What is the meaning of private in Ruby?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
rails8
  • 161
  • 1
  • 6
  • possible duplicate of [Protected and private methods in Rails](http://stackoverflow.com/questions/4495078/protected-and-private-methods-in-rails) – danielrsmith Sep 11 '15 at 20:07
  • Possible duplicate of [Why does Ruby have both private and protected methods?](http://stackoverflow.com/questions/3534449/why-does-ruby-have-both-private-and-protected-methods) – Nakilon Apr 10 '16 at 19:57

4 Answers4

13

Private methods cannot be called with an explicit receiver. But they can be called by any subclasses and instances of the class.

Here's a nice explanation of public, protected and private methods in Ruby.

Community
  • 1
  • 1
Daniel
  • 328
  • 3
  • 11
5

What private does in Ruby, unlike in other languages, is make so that methods can not be called with explicit receiver.

Aka, you can't call some_variable.some_private_method or even self.some_private_method.

That is all. They are still inherited. You can read more here.

ndnenkov
  • 35,425
  • 9
  • 72
  • 104
3

The subclass inherits all of the methods and attributes from the superclass, including it's private methods. You are, in fact, calling the private method belonging to the subclass.

What you couldn't do is call authorization_method from outside ApplicationController (or subclasses of Authorization controller. Try this in the console:

 > ApplicationController.new.authorization_method
 # NoMethodError: protected method `authorization_method' called for #<ApplicationController:0x0000000bb65778>
AJFaraday
  • 2,411
  • 1
  • 16
  • 39
2

As Daniel noted in his response private method "cannot be called with an explicit receiver". In another words, you cannot call private method using "dot" notation. This is different from Java where you can call this.privateMethod(). In Ruby self.private_method fails, but you can call it as private_method instead.

But there is one more way to call private methods of any object, which Rails internally uses to call before/after actions.

If you have an instance obj with private private_method, you can invoke the method by:

obj.send :private_method

Reality is, there are no private methods in Ruby in a strict sense. Privacy is "just recommendation, not the rule".

Community
  • 1
  • 1
dimakura
  • 7,575
  • 17
  • 36