【问题标题】:Require dependency to get Rails subclasses需要依赖才能获取 Rails 子类
【发布时间】:2013-05-15 16:21:51
【问题描述】:

我有以下设置:

app/models/my_module/service.rb

module MyModule
  class Service < ActiveRecord::Base
    def self.types
      self.subclasses
    end

    def self.raw_types
      self.types.map { |c| c.name.split("::").last }
    end
  end
end

require_dependency "my_module/service/rack"
require_dependency "my_module/service/rails"
require_dependency "my_module/service/sinatra"

app/models/my_module/service/rack.rb:

module MyModule
  class Service::Rack < Service
  end
end

app/models/my_module/service/rails.rb:

module MyModule
  class Service::Rails < Service
  end
end

app/models/my_module/service/sinatra.rb:

module MyModule
  class Service::Sinatra < Service
  end
end

到目前为止有效,但现在我的问题是:

为什么我必须添加这三行:

require_dependency "my_module/service/rack"
require_dependency "my_module/service/rails"
require_dependency "my_module/service/sinatra"

到我的 service.rb 文件?

如果我不添加这三行:

MyModule::Service.raw_types
=> []

如果我添加三行:

MyModule::Service.raw_types
=> ["Rack", "Rails", "Sinatra"]

有人有想法吗?

顺便说一句:我使用 Ruby 2.0.0-preview1、Rails 4.0.0.rc1 并使用

创建一个新的 Rails 引擎
rails plugin new MyModule

【问题讨论】:

  • MyModule::Service.types 工作吗?
  • 问题是为什么必须要求文件或为什么要填充数组?当您需要文件时,您添加 3 个类,它们都是 Service 的子类,因此 Service.subclasses 返回这 3 个类。
  • 想法:monkey-patches subclasses 到 Class 中的文件之一。
  • BettySt:仅当我需要父类中的文件时。 Kris:我的问题是为什么我必须 require 三个文件,而不是指向子类的方法调用自动需要我的文件,因为这些类是通过父类隐式调用的。用户:什么意思?我还没有定义任何猴子补丁。

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

默认情况下,在开发环境中,Rails 会自动加载 app 的常用子目录中的常量,方法是查看常规位置(例如,/app/models/my_module/service/rack.rb 对应于 MyModule::Service::Rack)。这种自动加载发生在第一次引用常量时,而不是在应用初始化时。

但这意味着在引用常量之前,除非明确要求,否则不会加载定义它的文件。

因此,当您调用 MyModule::Service.raw_types 时,如果尚未定义 MyModule::Service,则会从 app/models/my_module/service.rb 加载。但是,如果尚未对其子类进行引用,则不会定义这些常量除非明确需要定义它们的文件。因此,要求在该方法调用上自动加载 的文件中的那些文件使它们可用。

道德:如果你想确保MyModule::Service 的子类总是在MyModule::Service 存在时被定义,你需要在/app/models/my_module/service.rb 中要求它们

【讨论】:

  • 好吧,我已经想到了,但我希望 Rails 在调用方法时修复自动加载,因为通过父类方法调用需要这些类。这可能是 Rails 错误吗?我理解从“ruby 视图”加载,但不是从“rails 视图”加载..
  • 这不是 Rails 中的错误。当应用程序甚至不知道它们存在时,它应该如何知道需要这些常量?我认为在定义超类的文件中要求您的子类没有任何害处。或者,您可以将它们全部加载到 config/boot.rb 中,以便它们在应用初始化时出现。
  • 但是如果 Rails 有这样一种行为,它会搜索子文件夹,它像父类周围的模块一样被调用,以检查是否定义了子类,那就太好了。那太好了 :)。但无论如何,我只是通过 Rails 初始化过程加载它们。
  • 顺便说一句 +1 供您解释。
  • 所以根据这个解释,如果你遗漏了require_dependency,然后调用其中一个子类,例如MyModule::Service::Sinatra.new,如果下一个调用是MyModule::Service.raw_types,它会只返回['Sinatra'] 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 2014-05-19
  • 2022-12-18
  • 1970-01-01
  • 2018-07-24
相关资源
最近更新 更多