Skip to content

Commit

Permalink
Make serializers serializable, step 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Feb 5, 2016
1 parent 6b50b5d commit fb8a093
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,56 @@ def initialize(object, options = {})
end
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 = ActiveModel::Serializer::Adapter.create(self, { include: '*' }.merge!(adapter_opts))
adapter.serializable_hash
end
alias_method :to_hash, :serializable_hash
alias_method :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 fb8a093

Please sign in to comment.