module AbstractController::Helpers::ClassMethods
def _helpers_for_modification
def _helpers_for_modification unless @_helpers self._helpers = define_helpers_module(self, superclass._helpers) end _helpers end
def clear_helpers
Clears up all existing helpers in this class, only keeping the helper
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
def default_helper_module!
def default_helper_module! helper_prefix = name.delete_suffix("Controller") helper(helper_prefix) rescue NameError => e raise unless e.missing_name?("#{helper_prefix}Helper") end
def define_helpers_module(klass, helpers = nil)
def define_helpers_module(klass, helpers = nil) # In some tests inherited is called explicitly. In that case, just # return the module from the first time it was defined return klass.const_get(:HelperMethods) if klass.const_defined?(:HelperMethods, false) mod = Module.new klass.const_set(:HelperMethods, mod) mod.include(helpers) if helpers mod end
def helper(*args, &block)
end
end
"wadus"
def wadus
helper FooHelper, "woo", "bar/baz" do
Furthermore, all the above styles can be mixed together:
end
end
"wadus"
def wadus
helper do
+wadus+ method available in templates of the enclosing controller:
the context of the controller helper module. This simple call makes the
The method accepts a block too. If present, the block is evaluated in
The last two assume that "foo/bar".camelize returns "Foo::Bar".
helper :"foo/bar"
helper "foo/bar"
helper :"Foo::Bar"
helper "Foo::Bar"
# String/symbol without the "helper" suffix, camel or snake case.
helper Foo::BarHelper
# Module, recommended.
Namespaces are supported. The following calls include +Foo::BarHelper+:
yet loaded, it has to be autoloadable, which is normally the case.
object using String#constantize. Therefore, if the module has not been
When strings or symbols are passed, the method finds the actual module
The last two assume that "foo".camelize returns "Foo".
helper :foo
helper "foo"
helper :Foo
helper "Foo"
# String/symbol without the "helper" suffix, camel or snake case.
helper FooHelper
# Module, recommended.
include +FooHelper+:
Modules can be specified in different ways. All of the following calls
Includes the given modules in the template class.
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
def helper_method(*methods)
* method[, method] - A name or names of a method on the controller
==== Parameters
<% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
In a view:
end
end
current_user != nil
def logged_in?
end
@current_user ||= User.find_by(id: session[:user])
def current_user
private
helper_method :current_user, :logged_in?
class ApplicationController < ActionController::Base
to the view:
makes the +current_user+ and +logged_in?+ controller methods available
Declare a controller method as a helper. For example, the following
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
def inherited(klass)
This ensures that the parent class's module can be changed
When a class is inherited, wrap its helper module in a new module.
def inherited(klass) # Inherited from parent by default klass._helpers = nil klass.class_eval { default_helper_module! } unless klass.anonymous? super end