Ruby/关注/继承

Ruby / concerns / inheritance

使用 Ruby 3.1.1.

尝试实现类似于:https://github.com/mongodb/mongoid/blob/master/lib/mongoid/fields.rb :: class_attribute :fields

当我在 parent 模型上包含模型问题时,class_attribute 似乎在 child 模型上合并。我想在每个 child class 上维护一个单独的 class_attribute 散列,就像 mongoid Field 关注的那样。

这似乎只有在继承时才会发生。

module Dashboardable
  extend ActiveSupport::Concern

  included do
    class_attribute :dashboard_fields

    self.dashboard_fields = {}
  end

  class_methods do
    def dashboard_field(name, options = {})
      dashboard_fields[name] = options.merge(klass: self)
    end
  end
end

class Person
  include Mongoid::Document
  include Dashboardable

  dashboard_field :first_name
end

class Foo < Person
  dashboard_field :foot
  field :foot, type: String
end

class Bar < Person
  dashboard_field :bart
  field :bart, type: String
end

Foo.dashboard_fields: [:first_name, :foot]

Bar.dashboard_fields: [:first_name, :foot, :bart]

Foo.fields: ["_id", "_type", "foot"]

Bar.fields: ["_id", "_type", "bart"]

我进行了大量编辑并进行了一些挖掘,以找出问题所在以及发生了什么。对不起。

发生的事情是 class_attribute 所有 类 实际上在它们的实例属性中共享同一个对象。这是an intended behavior

如果您确保每个子类都获得“父散列”的副本,您实际上可以让它与 class_attribute 一起工作:

module Dashboardable
  extend ActiveSupport::Concern

  included do
    class_attribute :dashboard_fields, default: {}
  end

  class_methods do
    def inherited(subclass)
      subclass.class_eval { self.dashboard_fields = superclass.dashboard_fields.dup } 
    end

    def dashboard_field(name, options = {})
      dashboard_fields[name] = options.merge(klass: self)
    end
  end
end