Method visibility in Ruby (public, protected, and private methods) has been well explained in places like this blog post. But in Ruby on Rails it seems slightly different than it would be in a regular Ruby application because of the way the framework is set up. So, in Rails models, controllers, helpers, tests, etc., when is/isn't it appropriate to use protected or private methods?

Edit: Thanks for the answers so far. I understand the concept of protected and private in Ruby, but I'm looking more for an explanation of the typical way those types of visibility are used within the context of the various pieces of a Rails app (models, controllers, helpers, tests). For example, public controller methods are action methods, protected methods in the application controller are used for "helper methods" that need to be accessed by multiple controllers, etc.


For models, the idea is that the public methods are the public interface of the class. Public methods are intended to be used by other objects, while protected/private methods are to be hidden from the outside.

This is the same practice as in other object-oriented languages.

For controllers and tests, just do as you please. Both controller and test classes are only instantiated and called by the framework (yes, I know you can theoretically get the controller from the view, but if you do that, something is strange anyway). Since no one will ever create those things directly, there's nothing to "protect" against.

Addendum/Correction: For controllers, you should mark the "helper" methods as protected private, and only the actions themselves should be public. The framework will never route any incoming HTTP calls to actions/methods that are not public, so your helper methods should be protected in that way.

For helpers it will make no difference if a method is protected or private, since they are always called "directly".

You can mark stuff protected in all those cases if it makes things easier for you to understand, of course.


You use a private method if you want no one else but self to use a method. You use a protected method if you want something only self and is_a?(self) s can call.

A good use of protected might be if you had a "virtual" initialization method.

class Base
    def initialize()
        set_defaults()
        #other stuff
    end

    protected
    def set_defaults()
        # defaults for this type
        @foo = 7
        calculate_and_set_baz()
    end

    private
    def calculate_and_set_baz()
        @baz = "Something that only base classes have like a file handle or resource"
    end
end

class Derived < Base
    protected
    def set_defaults()
        @foo = 13
    end
end

@foo will have different values. and the Derived instances will not have @baz

Update: Since I wrote this, some things have changed in Ruby 2.0+ Aaron Patterson has an excellent write up http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html