Module: AbstractController::Helpers::ClassMethods

Defined in:
lib/abstract_controller/helpers.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#_helpers=(value) ⇒ Object (writeonly)

Sets the attribute _helpers

Parameters:

  • value

    the value to set the attribute _helpers to.



56
57
58
# File 'lib/abstract_controller/helpers.rb', line 56

def _helpers=(value)
  @_helpers = value
end

Instance Method Details

#_helpers_for_modificationObject



185
186
187
188
189
190
# File 'lib/abstract_controller/helpers.rb', line 185

def _helpers_for_modification
  unless @_helpers
    self._helpers = define_helpers_module(self, superclass._helpers)
  end
  _helpers
end

#clear_helpersObject

Clears up all existing helpers in this class, only keeping the helper with the same name as this class.



159
160
161
162
163
164
165
166
# File 'lib/abstract_controller/helpers.rb', line 159

def clear_helpers
  inherited_helper_methods = _helper_methods
  self._helpers = Module.new
  self._helper_methods = Array.new

  inherited_helper_methods.each { |meth| helper_method meth }
  default_helper_module! unless anonymous?
end

#helper(*args, &block) ⇒ Object

Includes the given modules in the template class.

Modules can be specified in different ways. All of the following calls include FooHelper:

# Module, recommended.
helper FooHelper

# String/symbol without the "helper" suffix, camel or snake case.
helper "Foo"
helper :Foo
helper "foo"
helper :foo

The last two assume that "foo".camelize returns “Foo”.

When strings or symbols are passed, the method finds the actual module object using String#constantize. Therefore, if the module has not been yet loaded, it has to be autoloadable, which is normally the case.

Namespaces are supported. The following calls include Foo::BarHelper:

# Module, recommended.
helper Foo::BarHelper

# String/symbol without the "helper" suffix, camel or snake case.
helper "Foo::Bar"
helper :"Foo::Bar"
helper "foo/bar"
helper :"foo/bar"

The last two assume that "foo/bar".camelize returns “Foo::Bar”.

The method accepts a block too. If present, the block is evaluated in the context of the controller helper module. This simple call makes the wadus method available in templates of the enclosing controller:

helper do
  def wadus
    "wadus"
  end
end

Furthermore, all the above styles can be mixed together:

helper FooHelper, "woo", "bar/baz" do
  def wadus
    "wadus"
  end
end


148
149
150
151
152
153
154
155
# File 'lib/abstract_controller/helpers.rb', line 148

def helper(*args, &block)
  modules_for_helpers(args).each do |mod|
    next if _helpers.include?(mod)
    _helpers_for_modification.include(mod)
  end

  _helpers_for_modification.module_eval(&block) if block_given?
end

#helper_method(*methods) ⇒ Object

Declare a controller method as a helper. For example, the following makes the current_user and logged_in? controller methods available to the view:

class ApplicationController < ActionController::Base
  helper_method :current_user, :logged_in?

  private
    def current_user
      @current_user ||= User.find_by(id: session[:user])
    end

    def logged_in?
      current_user != nil
    end
end

In a view:

<% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>

Parameters

  • method[, method] - A name or names of a method on the controller to be made available on the view.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/abstract_controller/helpers.rb', line 80

def helper_method(*methods)
  methods.flatten!
  self._helper_methods += methods

  location = caller_locations(1, 1).first
  file, line = location.path, location.lineno

  methods.each do |method|
    _helpers_for_modification.class_eval <<~ruby_eval, file, line
      def #{method}(*args, &block)                    # def current_user(*args, &block)
        controller.send(:'#{method}', *args, &block)  #   controller.send(:'current_user', *args, &block)
      end                                             # end
      ruby2_keywords(:'#{method}')
    ruby_eval
  end
end

#inherited(klass) ⇒ Object

When a class is inherited, wrap its helper module in a new module. This ensures that the parent class’s module can be changed independently of the child class’s.



48
49
50
51
52
53
54
# File 'lib/abstract_controller/helpers.rb', line 48

def inherited(klass)
  # Inherited from parent by default
  klass._helpers = nil

  klass.class_eval { default_helper_module! } unless klass.anonymous?
  super
end

#modules_for_helpers(modules_or_helper_prefixes) ⇒ Object

Given an array of values like the ones accepted by helper, this method returns an array with the corresponding modules, in the same order.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/abstract_controller/helpers.rb', line 170

def modules_for_helpers(modules_or_helper_prefixes)
  modules_or_helper_prefixes.flatten.map! do |module_or_helper_prefix|
    case module_or_helper_prefix
    when Module
      module_or_helper_prefix
    when String, Symbol
      helper_prefix = module_or_helper_prefix.to_s
      helper_prefix = helper_prefix.camelize unless helper_prefix.start_with?(/[A-Z]/)
      "#{helper_prefix}Helper".constantize
    else
      raise ArgumentError, "helper must be a String, Symbol, or Module"
    end
  end
end