将过滤器应用于ActiveModel Serializer属性以更改密钥

时间:2017-09-14 20:03:38

标签: ruby-on-rails active-model-serializers

我有一个用于我的rest API的序列化程序。目前,它看起来像:

class TestSerializer < ActiveModel::Serializer
    attributes :id, :name, :field_one__c, :field_two__c
end

我想知道是否有任何方法可以过滤所有字段,以便在序列化时删除__c,如果有办法将逻辑应用于所有字段。

案例是我最后有很多带__c的字段,我想在序列化程序级别使用最少量的代码删除所有字段。

1 个答案:

答案 0 :(得分:1)

是的,您可以使用:key选项在序列化程序中自定义属性名称

attribute :field_one__c, key: :field_one
attribute :field_two__c, key: :field_two

您还可以使用:if:unless选项制作任何条件属性。

Doc:https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/serializers.md#attribute

更新

对于您的特殊情况,您可以通过在属性列表之前定义attributes类方法来解决此问题:

class TestSerializer < ActiveModel::Serializer
  class << self
    def attributes(*attrs)
      attrs.each do |attr|
        options = {}
        options[:key] = attr.to_s[0..-4].to_sym if attr.to_s.end_with?('__c')

        attribute(attr, options)
      end
    end
  end

  attributes :id, :name, :field_one__c, :field_two__c
end

如果您有多个序列化程序类具有过滤大量属性的相同要求,则可以通过创建将继承自ActiveModel::Serializer的另一个序列化程序类在解决方案中应用DRY原则。将上面的类方法定义放在这个新的序列化程序中,并继承这个具有__c属性列表的新序列化程序。

class KeyFilterSerializer < ActiveModel::Serializer
  class << self
    def attributes(*attrs)
      attrs.each do |attr|
        options = {}
        options[:key] = attr.to_s[0..-4].to_sym if attr.to_s.end_with?('__c')

        attribute(attr, options)
      end
    end
  end
end

class TestSerializer < KeyFilterSerializer
  attributes :id, :name, :field_one__c, :field_two__c
end

class AnotherTestSerializer < KeyFilterSerializer
  attributes :id, :name, :field_one__c, :field_two__c
end