Strika
Strika

Reputation: 654

Where does Rails include modules in a class from lib?

We have a Rails application. There is a class in lib called PriorityFilter. It's a simple PORO class. It doesn't explicitly inherit from other classes and it doesn't include any modules. However, if I run Rails console I can see that the class includes a number of modules:

irb(main):002:0> PriorityFilter.included_modules
=> [ActiveSupport::ToJsonWithActiveSupportEncoder, ActionView::Helpers::NumberHelper, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, Kernel]

The class is used in a view helper, to prepare data for rendering a template. If I place a debugger brake point in the view helper and check included modules, there are even more modules in the list:

(byebug) PriorityFilter.included_modules
[ActiveSupport::ToJsonWithActiveSupportEncoder, ActionView::Helpers::UrlHelper, ApplicationHelper, DateTimeHelper, Aligni::DateTimeFormatter, ActiveJob::TestHelper, UnitHelper, ActionView::Helpers::TextHelper, ActionView::Helpers::TagHelper, ActionView::Helpers::OutputSafetyHelper, ActionView::Helpers::CaptureHelper, ActionView::Helpers::SanitizeHelper, ActionView::Helpers::NumberHelper, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, Kernel]

Among them are some helpers, such as ApplicationHelper, DateTimeHelper and UnitHelper that are actually defined in the application code, not Rails.

We checked thoroughly and these helpers are not explicitly included in this class (or other similar classes) anywhere in our application code. Because of that, I suspect that Rails does that. The questions are:

  1. Is it true that Rails does that for all classes in lib?
  2. Where does Rails include those modules?
  3. Are different modules included based on the context where a class is used? Is there a way to find out which modules will be included?
  4. Is there a way to control the list of included modules, via some configuration option? (I understand that modules can be explicitly included and that they can be included/excluded in runtime with methods available on every object.)

Upvotes: 2

Views: 667

Answers (1)

Marek Lipka
Marek Lipka

Reputation: 51161

Your class, unless specified otherwise, inherits from Object and the ActiveSupport adds its own extensions (also) to Object class, like here, with ActiveSupport::ToJsonWithActiveSupportEncoder for example:

[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
  klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
end

so to answer your specific questions:

  1. No, if you write class that inherits from BasicObject, none of it will be included, most probably.
  2. In various places, I gave you one example, you can search for another ones.
  3. No, it's based on inheritance chain.
  4. No, as far as I know.

I'm not sure though, how are the helpers included. I'd try something like this to find it out, with the usage of included hook:

module ApplicationHelper
  def self.included(base)
    binding.pry # or any other debugger
  end
end

And then I'd start the application and see the backtrace, maybe it would work.

Upvotes: 1

Related Questions