What does #self.included(base) do in Ruby on Rails' Restful Authentication?
Ruby on-RailsRestful AuthenticationRuby on-Rails Problem Overview
I thought we would do
helper_method :current_user, :logged_in?, :authorized?
to make these controller methods available for use as helper methods in views. But in Restful Authentication's lib/authenticated_system.rb
, I see:
# Inclusion hook to make #current_user and #logged_in?
# available as ActionView helper methods.
def self.included(base)
base.send :helper_method, :current_user, :logged_in?, :authorized? if base.respond_to? :helper_method
end
Why is it done this way instead of that single line? Also, I don't see included
being called anywhere.
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
The self.included
function is called when the module is included. It allows methods to be executed in the context of the base (where the module is included).
More info: a ruby mixin tutorial.
Solution 2 - Ruby on-Rails
Out of the same reason which Peter has mentioned I would like to add an example so that it's easy for the newbie developers to understand self.included(base) and self.extended(base) :
module Module1
def fun1
puts 'fun1 from Module1'
end
def self.included(_base)
def fun2
puts 'fun2 from Module1'
end
end
def self.extended(_base)
def fun3
puts 'fun3 from Module1'
end
end
end
module Module2
def foo
puts 'foo from Module2'
end
def self.extended(_base)
def bar
puts 'bar from Module2'
end
end
end
class Test
include Module1
extend Module2
def abc
puts 'abc form Test'
end
end
class Test2
extend Module1
end
Test.new.abc #=> abc form Test
Test.new.fun1 #=> fun1 from Module1
Test.new.fun2 #=> fun2 from Module1
Test.foo #=> foo from Module2
Test.bar #=> bar from Module2
Test.new.fun3 #=> **NoMethodError** (undefined method `fun3' ..)
*Test2*.fun3 #=> fun3 from Module1
-
extend : methods will be accessible as class methods
-
include : methods will be available as instance methods
-
"base" in self.extended(base) / self.included(base) : The base parameter in the static extended method will be either an instance object or class object of the class that extended the module depending whether you extend a object or class, respectively.
When a class includes a module the module’s self.included method will be invoked. The base parameter will be a class object for the class that includes the module.
Solution 3 - Ruby on-Rails
When the AuthenticatedSystem
method is included using the include
method, the self.included
method is triggered with whatever it was included into being the argument of base
.
The code you've shown calls helper_method
and defines some helpful helpers, but only if the base
has a helper_method
method.
It's done that way so including the module can set up the helper methods as well as adding additional methods to the class.
Solution 4 - Ruby on-Rails
As it is the first result when searching Google for "self.included(base)" I will try to give a small example on how it works. I don't know how much it differs from the restful-authentication-approach.
It is basically used to make methods from one module available in another module.
module One
def hello
puts 'hello from module One'
end
end
module Two
def self.included(base)
base.class_eval do
include One
end
end
end
class ExampleClass
include Two
end
ExampleClass.new.hello # => hello from module One
Solution 5 - Ruby on-Rails
Want to digger into self.included
and self.extended
?
Please look at here: https://ruby-doc.org/core-2.2.1/Module.html#method-i-included