我正在尝试创建一个关注点,该关注点包含来自包含类的字段映射。然后我需要根据所有映射的数据执行操作。这是我目前拥有的简化:
require 'active_support/concern'
module MyConcern
extend ActiveSupport::Concern
included do
end
def self.mapped_fields
# _ = [Test, Test2]
@@all_fields
end
class_methods do
def add_field(name)
@@all_fields ||= []
@@all_fields << name
end
end
end
class Test
include MyConcern
add_field :test
end
class Test2
include MyConcern
add_field :test_2
end
puts MyConcern.mapped_fields
# => [:test, :test_2]
虽然,如果我不急于加载包含的类
_ = [Test, Test2]
,@@all_fields
变量永远不会被触及。这使得在开发中使用它是不切实际的(我想它在生产中可以正常工作,因为默认情况下所有类都是急切加载的)。
是什么让我想知道这是否是正确的方法?看起来很奇怪.. Rubocop 说我应该用类实例变量(规则 Style/ClassVars)替换所有类变量,但我不知道如何用它产生相同的效果。
有更好的方法吗?我在第一次尝试时就完成了将映射存储到数据库中。但这似乎没有必要,因为所有映射都是以声明方式定义的,这也使得有必要将映射映射到数据库中,从而增加了复杂性。所以我想利用 ruby 的特性。
编辑原始问题的更多上下文
有问题的问题旨在跟踪许多设置了空白值的数据库列,以建议用户填写它们。 Concern 向包含它的模型添加更新/创建/销毁的触发器,它检查使用上述
add_field
方法定义的字段,但非简化版本看起来像这样
add_fields fields: {
FIELD_ONE: { filled: ->(parent) { parent&.field_one.present? } }
}
设置映射后,我可以为用户运行所有
filled
过程,并将空白字段呈现给前端。该解决方案不能很好解决的具体问题是拥有应该运行的 Procs 列表(为了获得我应该向用户建议的缺失字段)。