From 0f1ec7a3cf333c3f95c8225ea14c352a84f7bb53 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Wed, 16 May 2012 18:13:59 -0700 Subject: [PATCH] Add support for customizing fields --- lib/active_model/serializer.rb | 12 ++++++-- test/serializer_test.rb | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index d85b9500..91dd861b 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -246,12 +246,16 @@ module ActiveModel self._attributes = _attributes.dup attrs.each do |attr| - self._attributes[attr] = attr + attribute attr end end def attribute(attr, options={}) self._attributes = _attributes.merge(attr => options[:key] || attr) + + unless method_defined?(attr) + class_eval "def #{attr}() object.read_attribute_for_serialization(:#{attr}) end", __FILE__, __LINE__ + end end def associate(klass, attrs) #:nodoc: @@ -490,11 +494,15 @@ module ActiveModel hash = {} _attributes.each do |name,key| - hash[key] = @object.read_attribute_for_serialization(name) + hash[key] = read_attribute_for_serialization(name) end hash end + + def read_attribute_for_serialization(name) + send name + end end end diff --git a/test/serializer_test.rb b/test/serializer_test.rb index be562f31..4ddffe58 100644 --- a/test/serializer_test.rb +++ b/test/serializer_test.rb @@ -814,4 +814,58 @@ class SerializerTest < ActiveModel::TestCase ] }, actual) end + + def test_can_customize_attributes + serializer = Class.new(ActiveModel::Serializer) do + attributes :title, :body + + def title + object.title.upcase + end + end + + klass = Class.new do + def read_attribute_for_serialization(name) + { :title => "New post!", :body => "First post body" }[name] + end + + def title + read_attribute_for_serialization(:title) + end + + def body + read_attribute_for_serialization(:body) + end + end + + object = klass.new + + actual = serializer.new(object, :root => :post).as_json + + assert_equal({ + :post => { + :title => "NEW POST!", + :body => "First post body" + } + }, actual) + end + + def test_can_customize_attributes_with_read_attributes + serializer = Class.new(ActiveModel::Serializer) do + attributes :title, :body + + def read_attribute_for_serialization(name) + { :title => "New post!", :body => "First post body" }[name] + end + end + + actual = serializer.new(Object.new, :root => :post).as_json + + assert_equal({ + :post => { + :title => "New post!", + :body => "First post body" + } + }, actual) + end end