【问题标题】:Where does Rails include modules in a class from lib?Rails 在哪里包含来自 lib 的类中的模块?
【发布时间】:2019-03-07 09:30:45
【问题描述】:

我们有一个 Rails 应用程序。在lib 中有一个类叫做PriorityFilter。这是一个简单的 PORO 类。它没有显式继承自其他类,也不包含任何模块。但是,如果我运行 Rails 控制台,我可以看到该类包含许多模块:

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

该类在视图助手中使用,为渲染模板准备数据。如果我在视图助手中放置一个调试器刹车点并检查包含的模块,列表中的模块会更多:

(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]

其中有一些帮助器,例如ApplicationHelperDateTimeHelperUnitHelper,它们实际上是在应用程序代码中定义的,而不是Rails。

我们进行了彻底的检查,这些帮助程序并未明确包含在我们应用程序代码中的此类(或其他类似类)中。因此,我怀疑 Rails 会这样做。问题是:

  1. Rails 是否对 lib 中的所有类都这样做?
  2. Rails 在哪里包含这些模块?
  3. 是否根据使用类的上下文包含不同的模块?有没有办法找出将包含哪些模块?
  4. 有没有办法通过一些配置选项来控制包含的模块列表? (我知道模块可以被显式包含,并且可以在运行时使用每个对象上可用的方法来包含/排除它们。)

【问题讨论】:

标签: ruby-on-rails ruby


【解决方案1】:

除非另有说明,否则您的类继承自 Object 并且 ActiveSupport 将自己的扩展(也)添加到 Object 类,如 here,例如 ActiveSupport::ToJsonWithActiveSupportEncoder

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

所以回答您的具体问题:

  1. 不,如果您编写的类继承自 BasicObject,则很可能不会包含任何类。
  2. 在各个地方,我给你举了一个例子,你可以搜索其他的。
  3. 不,它基于继承链。
  4. 不,据我所知。

不过,我不确定,帮助程序是如何包括在内的。我会尝试这样的事情来找出它,使用included hook:

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

然后我会启动应用程序并查看回溯,也许它会起作用。

【讨论】:

  • 感谢您的回答。我知道 ActiveSupport 核心扩展已添加到 Object 的所有实例(#blank?#try 等)。但是,在我描述的示例中,应用程序代码(不是 Rails)中的一些模块包含在未明确包含它们的类中。你知道发生在哪里吗?另外,为什么应用程序中的一些助手会包含在一个类中,而另一些则不包含?
  • @Strika 哦,对不起,我读得不够仔细。我编辑了答案以提供可能的方法来找出它的来源,但我不确定它是否会起作用 - 如果不是,请告诉我,也许我们可以找到其他方法。
  • 我接受了这个答案,因为该建议帮助我们的团队在我们的应用程序中找到了一些有问题的地方。一个是在测试中,其中几个助手直接包含在Object 中,这导致了我描述的情况。另外,您提到的其他几点是正确的,关于使用BasicObject 的提示很棒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 2012-08-14
  • 2017-09-24
相关资源
最近更新 更多