Hello
I was reviewing some rails code lately and I see that in some cases
they use private methods (especially in application controller
methods). I understand that it is considered a good practice since the
methods aren’t used anywhere else outside of application controller,
but my question is:
What would happened if you never use private methods? Will it be some
security issue (and if yes, I’d like to see an example if it is
possible), is it just a good practice just to use methods inside the
scope of the class that it’s been used or is there any gains in
resources because there is narrower scope?
It might sound pretty newbie question but I am fairly new to OOP and
I’d like some guidance in this topics (even from some book or resource
about stuff like that).
Thank you
(I show a debate lately if there are any real advantages of OOP over
procedural programming and if OOP is just a myth and I am thinking
this a lot lately, so I decided to learn more about OOP and decide for
myself… I was also wondering if ruby and rails could be done with
procedural programming, instead of classes use functions and what it
couldn’t be done so easily).
What would happened if you never use private methods? Will it be some
security issue (and if yes, I’d like to see an example if it is
possible)
OK, here’s a quick example. Assuming you have the default routing rules
in
place so it handles /:controller/:action
class LoginsController < ApplicationController
def create
@user = User.login(params)
if @user.admin?
set_as_admin
else
set_as_normal
end
end
def set_as_admin
session[:user_type] = :admin
session[:user_id] = @user.id
end
def set_as_normal
session[:user_type] = :normal
session[:user_id] = @user.id
end
end
So you login with normal/password and it runs the internal method
“set_as_normal” to store the details in the session. You then visit
http://www.example.com/logins/set_as_admin and BOOM! You’re now an
administrator. This wouldn’t be possible if you put “private” above “def
set_as_admin”.
It’s a fairly simple example, and I wouldn’t code logins like that, but
it
shows that without declaring methods as private in controllers it gives
the
user an easy way to access them.
Just for completeness, the easiest protection for this in the real world
is
to 1) disable the default routing, 2)don’t use two methods for set_as_*
use one and do the admin? check in that method. However, it was a
simple
example off the top of my head as to why use private in a controller.
Cheers,
Andy
You opened my eyes! I haven’t figured out what private was. I thought
that you could access the method logins/set_as_admin even if it was
private because I thought by /logins/ you have access to the class,
that’s what I understood before when I read that private methods could
accessed by the class itself and only.
So, private methods can be accessed only by public methods of the
class, right? I wonder what protected is but I will search it and try
some examples. Thanks again
Private and protected methods can both be called from the same class
or a subclass (eg your controller classes typically inherit from
ApplicationController, your model classes typically inherit from
ActiveRecord::Base, etc). This is different from the conventions used
in many other languages like Java and C.
Private methods can only be called from the same instance of an
object. In the case of ApplicationController there will only be one
instance so it doesn’t matter but if you had a private method defined
in a model class this would come into play. A private method cannot
be called from any object except that object itself (the same
instance).
Protected methods can be called from an instance of the same class or
subclass.
So two instances of the same class can call each others’ protected
methods but not each others’ private methods.
Hope this helps!