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



188
189
190
191
192
193
# File 'lib/abstract_controller/helpers.rb', line 188

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.



162
163
164
165
166
167
168
169
# File 'lib/abstract_controller/helpers.rb', line 162

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


151
152
153
154
155
156
157
158
# File 'lib/abstract_controller/helpers.rb', line 151

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
96
97
98
# 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|
    # def current_user(*args, &block)
    #   controller.send(:'current_user', *args, &block)
    # end
    _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line
      def #{method}(*args, &block)
        controller.send(:'#{method}', *args, &block)
      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.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/abstract_controller/helpers.rb', line 173

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