ActiveModel :: Serializer包含属性前缀?

时间:2015-01-30 19:18:31

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

我正在使用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
}

我宁愿没有元编程解决方案,因为其他人会使用这个,我不希望他们恨我。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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