1

我有这个超级班

# encoding: utf-8

class EntidadeCte

  include ROXML
  include ActiveModel::Validations

  class << self
    # apelida o xml_accessor do ROXML para cte_attr
    alias :cte_attr :xml_accessor

    # define um accessor ruby comum para os atributos do cte
    def xml_accessor(*attrs)
      attr_accessor *attrs
    end

    # todos os atributos da entidade
    def cte_attrs
      roxml_attrs.map(&:attr_name)
    end

  end

  # todos os atributos da entidade do objeto
  def cte_attrs
    self.class.cte_attrs
  end

  # retorna o xml representando a entidade
  def to_cte
    doc = Nokogiri::XML::Document.new
    doc.root = to_xml
    doc.serialize
  end

  # retorna o xml ou delega a classe herdada
  def to_s
    self.respond_to? :to_cte ? to_cte : super
  end

end

和这个子类

# encoding: utf-8

    class TagCte < EntidadeCte

      def initialize
        self.xmlns = "http://www.portalfiscal.inf.br/cte"  
      end

      xml_name :CTe

      cte_attr :xmlns, :from => "@xmlns"
      cte_attr :infCte, :as => ConhecimentoTransporte

    end

我想做的是,一旦我调用to_cte我的子类对象,它就会返回它的属性值,但只有在对它们中的每一个应用一个函数之后。我想首先规范化它们的值(从字符串中删除重音符号、转义引号、特殊字符等)。在这种情况下我该怎么做?

4

1 回答 1

0

您在此处显示的代码显然缺少很多内容。我推测您的实体对象具有某些“属性”,这些属性只是通过链接到attr_accessor. 在 的特定子类(或子类)中EntitadeCte,您希望将一些特殊行为应用于这些“属性”。

子类的所有“属性”是否直接在该子类中定义?还是其中一些是遗传的?

如果它们直接在子类中定义,您可以简单地在子类中重新定义cte_attr,例如:

class Subclass < EntitadeCte
  def self.cte_attr(*attrs)
    attrs.each do |attr|
      attr_writer(attr)
      class_eval("def #{attr}; do something special to @#{attr} here; end")
    end
  end
end

attr_accessor因此,您可以定义自己的等效“类宏”,而不是使用,它为读者添加了一些特殊行为。

更新:从您的评论来看,听起来所有子类都EntitadeCte需要对属性进行相同的特殊处理。是对的吗?在这种情况下,您可以cte_attr将超类中的定义更改为类似于上面的示例代码。

或者,您可以定义cte_attr(在超类中)生成2 个读取器方法,一个用于规范化属性值,一个不规范化。然后编写一个to_cte使用“规范化”属性读取器的方法。

有各种各样的选择。如果我在这里给您的选择不能满足您的需求,那么您需要更具体地说明您想要做什么。问题是某些子类应该使用“规范化”属性,而其他子类应该使用“非规范化”属性吗?还是您要动态打开和关闭“规范化”的问题?

于 2012-09-11T14:31:55.193 回答