Ruby:如何在模块加载到其父类之前急于加载类内容

安德鲁

我上了几节课 SCHEMA

class Consumable::ProbeDesign < Consumable
  SCHEMA = {
    "type": "object",
    "properties": {  },
    "required": []
  }
end

class DataModule::WaterDeprivationLog < DataModule
  SCHEMA = {
    "type": "object",
    "properties": {
      "water_amount":         {"type": "decimal"},
      "notes":                {"type": "string"}
    },
    "required": []
  }
end

是STI计划中基类的孩子


class Consumable < ApplicationRecord
  include SingleTableInheritable
end

class DataModule < ApplicationRecord
  include SingleTableInheritable
end

然后我有一个模块,该模块需要为从包含该模块的类继承的所有类动态访问该常量

module SingleTableInheritable
  extend ActiveSupport::Concern

  included do
    def self.inherited(subclass)
      subclass.class_eval do
        schema = subclass::SCHEMA # NameError: uninitialized constant #<Class:0x0000560848920be8>::SCHEMA
        # then do some validations that rely on that schema value
      end

      super
    end
  end
end

但是在执行时以及如何调用的上下文中,它无法找到模块并返回 NameError: uninitialized constant #<Class:0x0000560848920be8>::SCHEMA

请注意,subclass.const_get("SCHEMA")也会失败

编辑:这是一个加载顺序问题。在类上运行之后,该常量立即可用,因为随后会加载该类。但是,通过尝试加载此类,模块将在加载时从父类继承,并且模块代码仍会在设置常量之前运行。

是否有某种类似继承的钩子,但允许所有内容预加载?

最高

实际上,这里的问题Module#included将始终在评估子类的主体之前运行。但这Module#included不是添加验证或回调的唯一方法。

您可以改为定义自己的“挂钩”:

module SingleTableInheritance
  extend ActiveSupport::Concern
  class_methods do
    def define_schema(hash)
      class_eval do
        const_set(:SCHEMA, hash)
        if self::SCHEMA["type"] == "object" 
          validates :something ...
        end
      end
    end
  end
end

define_schema只是一个开放本征类的普通旧类方法。这与在Rails和Ruby中到处普遍使用的模式相同,从生成setter和getter到验证甚至是回调都适用于所有模式。

用法:

class DataModule::WaterDeprivationLog < DataModule
  define_schema({
    type: "object",
    properties: {
      water_amount:         { type: "decimal"},
      notes:                { type: "string"}
    },
    required: []
  })
end

您还应该知道,您使用的“短”哈希语法将键强制为符号:

irb(main):033:0> {"foo": "bar" }
=> {:foo=>"bar"}

如果要使用字符串作为键,请改用hashrockets =>{"foo": "bar" }由于意图不明确,因此被视为不良形式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在加载类之前修改它?

如何在加载到类加载器的类中强制转换对象

Wildfly模块类加载

动态内容未加载到扩展组件的 React 类中

在类加载之前运行方法

如何转储加载到内存中的类?爪哇

重新加载模块/类后仍定义Ruby方法

自动加载模块中的类

如何在util类上加载属性

如何在Java中加载嵌套类?

如何在加载类时运行代码?

如何在Fragment类中加载WebView?

如何在加载类前面显示图层

如何在偏好设置之前显示加载屏幕类[Libgdx和android]

如何在初始化类方法之前加载Kivy ID(带有Kivy的Python)

在ruby中,如何将原始源代码加载到Proc的实例?(在类方法中将`before`之后的钩子添加)

在内容脚本加载到Chrome扩展程序之前,如何避免出现样式错误的内容?

使用 Picasso 将类加载到 val

如何在使用 ajax 将 PHP 文件加载到 DIV 之前显示加载器?

如何在文档级加载项中将C#类公开给VBA模块?

如何在Rails 5应用程序中正确加载lib模块和类

类加载器如何在清单类路径中加载类引用?

如何在类路径之外加载 java 类?

如何在另一个模块加载之前加载一个模块?

如何操作它加载之前一类的字节码?

在PageLoad上添加类之前,如何确保元素已加载

Perl6:如何动态加载类模块?

如何将 JSON 数据加载到 Angular 中的类或类数组中?

我如何急于使用自己的键将关系直接加载到父级而不循环?