0

I am using AMS to comply with an older API and attempting to include a prefix on each attribute.

Suppose i have this serializer:

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
}

and would like the output to be:

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
}

I would prefer to not metaprogram a solution as other people will be using this and I don't want them to hate me.

lightswitch05
  • 9,058
  • 7
  • 52
  • 75
Blair Anderson
  • 19,463
  • 8
  • 77
  • 114

2 Answers2

0

Rails 4 adds a handy Hash#transform_keys method that makes this particularly easy.

class InvoiceSerializer
  # ...
  KEY_PREFIX = "invoice_"

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

If you're stuck with Rails 3, it's easy to do the same thing without transform_keys:

def serializable_hash(*args)
  hash = super

  hash.each_with_object({}) do |(key, val), result|
    result[:"#{KEY_PREFIX}#{key}"] = val
  end
end
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
0

transform_keys only works in rails 4. Rails3 solution would be to reimplement 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

and inside serializer would be:

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
Blair Anderson
  • 19,463
  • 8
  • 77
  • 114