Что делает # self.included (base) в Restful-аутентификации Ruby on Rails? - PullRequest
51 голосов
/ 02 марта 2011

Я думал, что мы сделаем

helper_method :current_user, :logged_in?, :authorized?

, чтобы сделать эти методы контроллера доступными для использования в качестве вспомогательных методов в представлениях. Но в lib/authenticated_system.rb Restful Authentication я вижу:

# 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

Почему это делается вместо одной строки? Кроме того, я не вижу, чтобы included звонили куда-либо.

Ответы [ 5 ]

96 голосов
/ 02 марта 2011

Функция self.included вызывается, когда модуль включен. Это позволяет выполнять методы в контексте базы (где включен модуль).

Дополнительная информация: учебник по ruby ​​mixin .

12 голосов
/ 02 марта 2011

Когда метод AuthenticatedSystem включается с использованием метода include, метод self.included запускается с тем, что было включено в аргумент base.

Код, который вы показали, вызывает helper_method и определяет некоторых полезных помощников, но только если base имеет метод helper_method.

Это сделано таким образом, что включение модуля может устанавливать вспомогательные методы, а также добавлять дополнительные методы в класс.

11 голосов
/ 03 января 2017

По той же причине, о которой упоминал Питер, я хотел бы добавить пример, чтобы новичкам-разработчикам было легко понять self.included (base) и self.extended (base ) :

module Module1
 def fun1
    puts "fun1 from Module1"
 end

 def self.included(base)
    def fun2
        puts "fun2 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

Test.new.abc # => abc form Test

Test.new.fun1 # => fun1 из Module1

Test.new.fun2 # => fun2 из Module1

Test.foo # => foo из Module2

Test.bar # => бар из Module2

extend: методы будут доступны как методы класса

include: методы будут доступны как методы экземпляра

" base " в self.extended ( base ) / self.included ( base ):

Базовым параметром в статическом расширенном методе будет либо объект экземпляра, либо объект класса класса, который расширил модуль в зависимости от того, расширяете ли вы объект или класс, соответственно.

Когда класс включает модуль, вызывается метод self.included модуля. Базовым параметром будет объект класса для класса, в который входит модуль.

5 голосов
/ 04 августа 2016

Поскольку это первый результат при поиске в Google слова «self.included (base)», я попытаюсь привести небольшой пример того, как он работает. Я не знаю, насколько это отличается от подхода restful-аутентификации.

Он в основном используется, чтобы сделать методы из одного модуля доступными в другом модуле.

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
1 голос
/ 24 марта 2017

Хотите копать в self.included и self.extended?

Пожалуйста, посмотрите здесь: https://ruby -doc.org / core-2.2.1 / Module.html # method-i-includes

...