【问题标题】:Access fields of child classes [closed]子类的访问字段[关闭]
【发布时间】:2015-01-25 23:05:56
【问题描述】:

编辑:对不起,我忘了提到我使用的是 Mongoid,那些 field 是 Mongoid 的

我有一个 Rails 应用程序,负责生成 Word 文档(并替换其中的一些变量)

所以我有许多DocumentEtude::xxxx 类超类基类DocumentEtude 类(英文ProjectDocument

class DocumentEtude
  include Mongoid::Document
  field :shared_field
class DocumentEtude:xxxx < DocumentEtude
  field :only_in_xxxx_field

为了保持理智,我想将所有变量放在一个地方,然后执行类似的操作

class DocumentEtude
    ...
    def variables
            vars = {}
            case _type
            when 'DocumentEtude::xxxxx', 'DocumentEtude::yyyyyy', 'DocumentEtude::zzzzzz'
                vars.merge!({
                    "some_var" => shared_field,
                    "some_var2" => only_in_xxxx_field
                    ...
    end

    def generate_document
      # Code that uses the variables defined before
    end

现在的问题是我在 DocumentEtude 中声明了这个方法,但是 我需要访问一些仅在子类中声明的字段(例如only_in_xxxx_field),但显然 Ruby 无法找到它们。知道我该怎么做吗?

【问题讨论】:

  • 你能举例说明你想如何访问它们吗?
  • 我重新编辑了我的问题。例如,我可能有一个DocumentEtude::Bill,其中我有额外的字段pricetax 等。我想将这些变量放在一个哈希中(然后用于替换我的 word 文档的 xml 中的内容)
  • fields类方法或attributes实例方法有问题吗?您不能从这些开始并过滤掉通常的嫌疑人吗?
  • bang bang ...是我的头撞在墙上的声音,因为我犯了这样一个愚蠢的错误。我意识到我只做了一个case when 并将相同的文档类型放入多个when。所以很明显,只有第一个会被执行,只合并一小部分实际变量,给我的印象是有些东西不能正常工作......
  • 查看我的上一条评论...这确实是一个愚蠢的错误,并不能使它成为一个真正的问题。

标签: ruby-on-rails ruby inheritance mongoid


【解决方案1】:

如果我理解您的问题,您希望有某种设置,它是沿类层次结构继承的。如果是这种情况,请使用 ActiveSupport 的核心扩展 class_attribute。例如(复制自rails guide

class A
  class_attribute :x
end

class B < A; end

class C < B; end

A.x = :a
B.x # => :a
C.x # => :a

B.x = :b
A.x # => :a
C.x # => :b

C.x = :c
A.x # => :a
B.x # => :b

您唯一必须注意的是mutables(就像您正在使用的哈希一样)。但是,由于在您的情况下,甚至希望子类覆盖超类的值,所以您很高兴。

【讨论】:

  • 对不起,我不是在谈论类属性,而是实例属性。但是我不知道这个 ActiveSupport,它在其他地方对我有用。
  • 您的 case 语句使用类类型,而您的字段语句将值绑定到类。此外,class_attribute 为您提供实例级别的 setter 和 getter。
  • 啊,是的实例级别设置器和获取器。抱歉,我在阅读您的链接时首先错过了这一行:它们也可以在实例级别访问和覆盖
【解决方案2】:

您总是可以定义一个方法来返回您在子类中定义的字段并在您的父类方法中调用它。

例子

class DocumentEtude
    def variables
            vars = {}
            vars.merge!(
              "some_var" => shared_field,
              "some_var2" => your_customized_field)
            ...
    end
end

class DocumentEtude::XXXX < DocumentEtude
  field :only_in_xxxx_field

  def your_customized_field
    return only_in_xxxx_field
  end
end

当然,如果父类试图访问的某些字段未在子类中定义,最好将其添加到父类中:

def your_customized_field
  raise NotImplementedError, "This field is not defined yet!"
end

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 2015-02-25
    • 2011-05-29
    • 2015-10-07
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    相关资源
    最近更新 更多