What does #self.included(base) do in Ruby on Rails' Restful Authentication?

Ruby on-RailsRestful Authentication

Ruby 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnonopolarityView Question on Stackoverflow
Solution 1 - Ruby on-RailsnathanvdaView Answer on Stackoverflow
Solution 2 - Ruby on-RailsFaaduBaalakView Answer on Stackoverflow
Solution 3 - Ruby on-RailsRyan BiggView Answer on Stackoverflow
Solution 4 - Ruby on-RailsPeter PiperView Answer on Stackoverflow
Solution 5 - Ruby on-RailsLaneView Answer on Stackoverflow