From 08716d20c91d321b69e8b3720efdb7c5c4ecb7ec Mon Sep 17 00:00:00 2001 From: Gary Gordon Date: Thu, 6 Nov 2014 11:10:15 -0500 Subject: [PATCH] Rename attribute with :key (0.8.x compatibility) --- README.md | 12 ++++++++++++ lib/active_model/serializer.rb | 9 ++++++++- test/fixtures/poro.rb | 5 +++++ test/serializers/attribute_test.rb | 23 +++++++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/serializers/attribute_test.rb diff --git a/README.md b/README.md index 1d9db323..6bb70f3a 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,18 @@ ActiveModel::Serializer.config.adapter = :hal You won't need to implement an adapter unless you wish to use a new format or media type with AMS. +If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the :key option to customize it: + +```ruby +class PostSerializer < ActiveModel::Serializer + attributes :id, :body + + # look up :subject on the model, but use +title+ in the JSON + attribute :subject, :key => :title + has_many :comments +end +``` + In your controllers, when you use `render :json`, Rails will now first search for a serializer for the object and use it if available. diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index dbc2060d..9f9c91db 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -21,7 +21,6 @@ module ActiveModel def self.attributes(*attrs) @_attributes.concat attrs - attrs.each do |attr| define_method attr do object.read_attribute_for_serialization(attr) @@ -29,6 +28,14 @@ module ActiveModel end end + def self.attribute(attr, options = {}) + key = options.fetch(:key, attr) + @_attributes.concat [key] + define_method key do + object.read_attribute_for_serialization(attr) + end unless method_defined?(key) + end + # Defines an association in the object should be rendered. # # The serializer object should implement the association name diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 4f584fed..f7c1becb 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -95,3 +95,8 @@ PaginatedSerializer = Class.new(ActiveModel::Serializer::ArraySerializer) do 'paginated' end end + +AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do + attribute :id + attribute :name, key: :title +end diff --git a/test/serializers/attribute_test.rb b/test/serializers/attribute_test.rb new file mode 100644 index 00000000..35f27ee4 --- /dev/null +++ b/test/serializers/attribute_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' + +module ActiveModel + class Serializer + class AttributeTest < Minitest::Test + def setup + @blog = Blog.new({ id: 1, name: 'AMS Hints' }) + @blog_serializer = AlternateBlogSerializer.new(@blog) + end + + def test_attributes_definition + assert_equal([:id, :title], + @blog_serializer.class._attributes) + end + + def test_json_serializable_hash + adapter = ActiveModel::Serializer::Adapter::Json.new(@blog_serializer) + assert_equal({:id=>1, :title=>"AMS Hints"}, adapter.serializable_hash) + end + end + end +end +