开发者

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

开发者 https://www.devze.com 2023-02-14 17:50 出处:网络
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/auth

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:

# In开发者_如何转开发clusion 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.


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.


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.


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.


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


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

0

精彩评论

暂无评论...
验证码 换一张
取 消