Skip to content

Commit

Permalink
Merge pull request #1494 from bf4/serializable_serializer
Browse files Browse the repository at this point in the history
Make serializers serializable, step 1.
  • Loading branch information
bf4 committed Mar 13, 2016
2 parents b6343a5 + b169ed3 commit 0d1f770
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Breaking changes:

Features:
- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
(using the Attributes adapter by default). (@bf4)
- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
Rails url_helpers to `SerializationContext` for use in links. (@remear, @bf4)
- [#1004](https://github.com/rails-api/active_model_serializers/pull/1004) JSON API errors object implementation.
Expand Down
51 changes: 51 additions & 0 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,57 @@ def success?
true
end

# @return [Hash] containing the attributes and first level
# associations, similar to how ActiveModel::Serializers::JSON is used
# in ActiveRecord::Base.
#
# TODO: Move to here the Attributes adapter logic for
# +serializable_hash_for_single_resource(options)+
# and include <tt>ActiveModel::Serializers::JSON</tt>.
# So that the below is true:
# @param options [nil, Hash] The same valid options passed to `serializable_hash`
# (:only, :except, :methods, and :include).
#
# See
# https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serializers/json.rb#L17-L101
# https://github.com/rails/rails/blob/v5.0.0.beta2/activemodel/lib/active_model/serialization.rb#L85-L123
# https://github.com/rails/rails/blob/v5.0.0.beta2/activerecord/lib/active_record/serialization.rb#L11-L17
# https://github.com/rails/rails/blob/v5.0.0.beta2/activesupport/lib/active_support/core_ext/object/json.rb#L147-L162
#
# @example
# # The :only and :except options can be used to limit the attributes included, and work
# # similar to the attributes method.
# serializer.as_json(only: [:id, :name])
# serializer.as_json(except: [:id, :created_at, :age])
#
# # To include the result of some method calls on the model use :methods:
# serializer.as_json(methods: :permalink)
#
# # To include associations use :include:
# serializer.as_json(include: :posts)
# # Second level and higher order associations work as well:
# serializer.as_json(include: { posts: { include: { comments: { only: :body } }, only: :title } })
def serializable_hash(adapter_opts = nil)
adapter_opts ||= {}
adapter_opts = { include: '*', adapter: :attributes }.merge!(adapter_opts)
adapter = ActiveModelSerializers::Adapter.create(self, adapter_opts)
adapter.serializable_hash(adapter_opts)
end
alias to_hash serializable_hash
alias to_h serializable_hash

# @see #serializable_hash
# TODO: When moving attributes adapter logic here, @see #serializable_hash
# So that the below is true:
# @param options [nil, Hash] The same valid options passed to `as_json`
# (:root, :only, :except, :methods, and :include).
# The default for `root` is nil.
# The default value for include_root is false. You can change it to true if the given
# JSON string includes a single root node.
def as_json(adapter_opts = nil)
serializable_hash(adapter_opts)
end

# Used by adapter as resource root.
def json_key
root || object.class.model_name.to_s.underscore
Expand Down
55 changes: 55 additions & 0 deletions test/serializers/serialization_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module ActiveModel
class Serializer
class SerializationTest < ActiveSupport::TestCase
class Blog < ActiveModelSerializers::Model
attr_accessor :id, :name, :authors
end
class Author < ActiveModelSerializers::Model
attr_accessor :id, :name
end
class BlogSerializer < ActiveModel::Serializer
attributes :id
attribute :name, key: :title

has_many :authors
end
class AuthorSerializer < ActiveModel::Serializer
attributes :id, :name
end

setup do
@authors = [Author.new(id: 1, name: 'Blog Author')]
@blog = Blog.new(id: 2, name: 'The Blog', authors: @authors)
@serializer_instance = BlogSerializer.new(@blog)
@serializable = ActiveModel::SerializableResource.new(@blog, serializer: BlogSerializer, adapter: :attributes)
@expected_hash = { id: 2, title: 'The Blog', authors: [{ id: 1, name: 'Blog Author' }] }
@expected_json = '{"id":2,"title":"The Blog","authors":[{"id":1,"name":"Blog Author"}]}'
end

test '#serializable_hash is the same as generated by the attributes adapter' do
assert_equal @serializable.serializable_hash, @serializer_instance.serializable_hash
assert_equal @expected_hash, @serializer_instance.serializable_hash
end

test '#as_json is the same as generated by the attributes adapter' do
assert_equal @serializable.as_json, @serializer_instance.as_json
assert_equal @expected_hash, @serializer_instance.as_json
end

test '#to_json is the same as generated by the attributes adapter' do
assert_equal @serializable.to_json, @serializer_instance.to_json
assert_equal @expected_json, @serializer_instance.to_json
end

test '#to_h is an alias for #serializable_hash' do
assert_equal @serializable.serializable_hash, @serializer_instance.to_h
assert_equal @expected_hash, @serializer_instance.to_h
end

test '#to_hash is an alias for #serializable_hash' do
assert_equal @serializable.serializable_hash, @serializer_instance.to_hash
assert_equal @expected_hash, @serializer_instance.to_hash
end
end
end
end

0 comments on commit 0d1f770

Please sign in to comment.