【问题标题】:ActiveModel::Serializer include attribute prefix?ActiveModel::Serializer 包含属性前缀?
【发布时间】:2015-01-30 19:18:31
【问题描述】:

我正在使用 AMS 来遵守较旧的 API,并尝试在每个属性上包含前缀。

假设我有这个序列化器:

InvoiceSerializer.new(invoice).serializable_hash
=> {
 :id=>662473,
 :number=>"3817",
 :created_at=>Tue, 27 Jan 2015 14:55:51 PST -08:00,
 :updated_at=>Tue, 27 Jan 2015 14:56:20 PST -08:00,
 :date=>Tue, 27 Jan 2015,
 :subtotal=>#<BigDecimal:7fa89e051380,'0.1E3',9(18)>,
 :total=>#<BigDecimal:7fa89e050f70,'0.1095E3',18(18)>,
 :tax=>#<BigDecimal:7fa89e050d40,'0.95E1',18(18)>,
 :verified_paid=>false,
 :tech_marked_paid=>true,
 :ticket_id=>11111
}

并希望输出为:

InvoiceSerializer.new(invoice).serializable_hash
=> {
 :invoice_id=>662473,
 :invoice_number=>"3817",
 :invoice_created_at=>Tue, 27 Jan 2015 14:55:51 PST -08:00,
 :invoice_updated_at=>Tue, 27 Jan 2015 14:56:20 PST -08:00,
 :invoice_date=>Tue, 27 Jan 2015,
 :invoice_subtotal=>#<BigDecimal:7fa89e051380,'0.1E3',9(18)>,
 :invoice_total=>#<BigDecimal:7fa89e050f70,'0.1095E3',18(18)>,
 :invoice_tax=>#<BigDecimal:7fa89e050d40,'0.95E1',18(18)>,
 :invoice_verified_paid=>false,
 :invoice_tech_marked_paid=>true,
 :invoice_ticket_id=>11111
}

我宁愿不对解决方案进行元编程,因为其他人会使用它,我不希望他们讨厌我。

【问题讨论】:

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


    【解决方案1】:

    Rails 4 添加了一个方便的Hash#transform_keys 方法,使这变得特别容易。

    class InvoiceSerializer
      # ...
      KEY_PREFIX = "invoice_"
    
      def serializable_hash(*args)
        hash = super
        hash.transform_keys {|key| :"#{KEY_PREFIX}#{key}" }
      end
    end
    

    如果你被 Rails 3 卡住了,不用transform_keys 也很容易做同样的事情:

    def serializable_hash(*args)
      hash = super
    
      hash.each_with_object({}) do |(key, val), result|
        result[:"#{KEY_PREFIX}#{key}"] = val
      end
    end
    

    【讨论】:

    • transform_keys 仅适用于 rails4
    • 我假设您使用的是 Rails 4(大约两年前发布),因为您没有另外指定。我已经用没有transform_keys 的版本更新了我的答案。
    【解决方案2】:

    transform_keys 仅适用于 rails 4。Rails3 的解决方案是重新实现 transform_keys :)

    source

    # File activesupport/lib/active_support/core_ext/hash/keys.rb, line 8
      def transform_keys
        result = {}
        each_key do |key|
          result[yield(key)] = self[key]
        end
        result
      end
    

    内部序列化器将是:

    class InvoiceSerializer
      # ...
      KEY_PREFIX = "invoice_"
    
      def serializable_hash(*args)
        hash = super
        result = {}
        hash.each_key {|key| result["#{KEY_PREFIX}#{key}"] = hash[key] }
        result
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多