mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Merge pull request #962 from joaomdmoura/render-array-objects
Rendering objects that doesn't have serializers
This commit is contained in:
commit
03ac94b9b4
@ -39,17 +39,18 @@ module ActionController
|
|||||||
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
|
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
|
||||||
|
|
||||||
if use_adapter? && (serializer = get_serializer(resource))
|
if use_adapter? && (serializer = get_serializer(resource))
|
||||||
|
|
||||||
@_serializer_opts[:scope] ||= serialization_scope
|
@_serializer_opts[:scope] ||= serialization_scope
|
||||||
@_serializer_opts[:scope_name] = _serialization_scope
|
@_serializer_opts[:scope_name] = _serialization_scope
|
||||||
|
|
||||||
# omg hax
|
begin
|
||||||
object = serializer.new(resource, @_serializer_opts)
|
serialized = serializer.new(resource, @_serializer_opts)
|
||||||
adapter = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts)
|
rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError
|
||||||
super(adapter, options)
|
else
|
||||||
else
|
resource = ActiveModel::Serializer::Adapter.create(serialized, @_adapter_opts)
|
||||||
super(resource, options)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
super(resource, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -206,10 +206,16 @@ module ActiveModel
|
|||||||
serializer_class = ActiveModel::Serializer.serializer_for(association_value, association_options)
|
serializer_class = ActiveModel::Serializer.serializer_for(association_value, association_options)
|
||||||
|
|
||||||
if serializer_class
|
if serializer_class
|
||||||
serializer = serializer_class.new(
|
begin
|
||||||
association_value,
|
serializer = serializer_class.new(
|
||||||
options.except(:serializer).merge(serializer_from_options(association_options))
|
association_value,
|
||||||
)
|
options.except(:serializer).merge(serializer_from_options(association_options))
|
||||||
|
)
|
||||||
|
rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError
|
||||||
|
virtual_value = association_value
|
||||||
|
virtual_value = virtual_value.as_json if virtual_value.respond_to?(:as_json)
|
||||||
|
association_options[:association_options][:virtual_value] = virtual_value
|
||||||
|
end
|
||||||
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
||||||
association_options[:association_options][:virtual_value] = association_value
|
association_options[:association_options][:virtual_value] = association_value
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
module ActiveModel
|
module ActiveModel
|
||||||
class Serializer
|
class Serializer
|
||||||
class ArraySerializer
|
class ArraySerializer
|
||||||
|
NoSerializerError = Class.new(StandardError)
|
||||||
include Enumerable
|
include Enumerable
|
||||||
delegate :each, to: :@objects
|
delegate :each, to: :@objects
|
||||||
|
|
||||||
@ -13,7 +14,12 @@ module ActiveModel
|
|||||||
:serializer,
|
:serializer,
|
||||||
ActiveModel::Serializer.serializer_for(object)
|
ActiveModel::Serializer.serializer_for(object)
|
||||||
)
|
)
|
||||||
serializer_class.new(object, options.except(:serializer))
|
|
||||||
|
if serializer_class.nil?
|
||||||
|
fail NoSerializerError, "No serializer found for object: #{object.inspect}"
|
||||||
|
else
|
||||||
|
serializer_class.new(object, options.except(:serializer))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@meta = options[:meta]
|
@meta = options[:meta]
|
||||||
@meta_key = options[:meta_key]
|
@meta_key = options[:meta_key]
|
||||||
|
|||||||
@ -47,6 +47,14 @@ module ActionController
|
|||||||
render json: @post
|
render json: @post
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_json_object_without_serializer
|
||||||
|
render json: {error: 'Result is Invalid'}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_json_array_object_without_serializer
|
||||||
|
render json: [{error: 'Result is Invalid'}]
|
||||||
|
end
|
||||||
|
|
||||||
def update_and_render_object_with_cache_enabled
|
def update_and_render_object_with_cache_enabled
|
||||||
@post.updated_at = DateTime.now
|
@post.updated_at = DateTime.now
|
||||||
|
|
||||||
@ -160,6 +168,20 @@ module ActionController
|
|||||||
assert_equal expected.to_json, @response.body
|
assert_equal expected.to_json, @response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_render_json_object_without_serializer
|
||||||
|
get :render_json_object_without_serializer
|
||||||
|
|
||||||
|
assert_equal 'application/json', @response.content_type
|
||||||
|
assert_equal ({error: 'Result is Invalid'}).to_json, @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_json_array_object_without_serializer
|
||||||
|
get :render_json_array_object_without_serializer
|
||||||
|
|
||||||
|
assert_equal 'application/json', @response.content_type
|
||||||
|
assert_equal ([{error: 'Result is Invalid'}]).to_json, @response.body
|
||||||
|
end
|
||||||
|
|
||||||
def test_render_array_using_implicit_serializer
|
def test_render_array_using_implicit_serializer
|
||||||
get :render_array_using_implicit_serializer
|
get :render_array_using_implicit_serializer
|
||||||
assert_equal 'application/json', @response.content_type
|
assert_equal 'application/json', @response.content_type
|
||||||
|
|||||||
@ -8,7 +8,7 @@ module ActiveModel
|
|||||||
def setup
|
def setup
|
||||||
ActionController::Base.cache_store.clear
|
ActionController::Base.cache_store.clear
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@post = Post.new(title: 'New Post', body: 'Body')
|
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||||
@post.comments = [@first_comment, @second_comment]
|
@post.comments = [@first_comment, @second_comment]
|
||||||
@ -17,20 +17,31 @@ module ActiveModel
|
|||||||
@second_comment.post = @post
|
@second_comment.post = @post
|
||||||
@blog = Blog.new(id: 1, name: "My Blog!!")
|
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||||
@post.blog = @blog
|
@post.blog = @blog
|
||||||
|
@tag = Tag.new(id: 1, name: "#hash_tag")
|
||||||
@serializer = PostSerializer.new(@post)
|
@post.tags = [@tag]
|
||||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many
|
def test_has_many
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
|
||||||
assert_equal([
|
assert_equal([
|
||||||
{id: 1, body: 'ZOMG A COMMENT'},
|
{id: 1, body: 'ZOMG A COMMENT'},
|
||||||
{id: 2, body: 'ZOMG ANOTHER COMMENT'}
|
{id: 2, body: 'ZOMG ANOTHER COMMENT'}
|
||||||
], @adapter.serializable_hash[:post][:comments])
|
], adapter.serializable_hash[:post][:comments])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_has_many_with_no_serializer
|
||||||
|
serializer = PostWithTagsSerializer.new(@post)
|
||||||
|
adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
|
||||||
|
assert_equal({
|
||||||
|
id: 42,
|
||||||
|
tags: [
|
||||||
|
{"attributes"=>{"id"=>1, "name"=>"#hash_tag"}}
|
||||||
|
]
|
||||||
|
}.to_json, adapter.serializable_hash[:post_with_tags].to_json)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,8 @@ module ActiveModel
|
|||||||
@blog.articles = [@post]
|
@blog.articles = [@post]
|
||||||
@post.blog = @blog
|
@post.blog = @blog
|
||||||
@post_without_comments.blog = nil
|
@post_without_comments.blog = nil
|
||||||
|
@tag = Tag.new(id: 1, name: "#hash_tag")
|
||||||
|
@post.tags = [@tag]
|
||||||
@serializer = PostSerializer.new(@post)
|
@serializer = PostSerializer.new(@post)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||||
end
|
end
|
||||||
@ -95,6 +96,7 @@ module ActiveModel
|
|||||||
serializer = BlogSerializer.new(@blog)
|
serializer = BlogSerializer.new(@blog)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
actual = adapter.serializable_hash[:data][:relationships][:articles]
|
actual = adapter.serializable_hash[:data][:relationships][:articles]
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
data: [{
|
data: [{
|
||||||
type: "posts",
|
type: "posts",
|
||||||
@ -103,6 +105,21 @@ module ActiveModel
|
|||||||
}
|
}
|
||||||
assert_equal expected, actual
|
assert_equal expected, actual
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_has_many_with_no_serializer
|
||||||
|
serializer = PostWithTagsSerializer.new(@post)
|
||||||
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: "1",
|
||||||
|
type: "posts",
|
||||||
|
relationships: {
|
||||||
|
tags: { data: nil }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, adapter.serializable_hash)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
7
test/fixtures/poro.rb
vendored
7
test/fixtures/poro.rb
vendored
@ -76,6 +76,7 @@ Role = Class.new(Model)
|
|||||||
User = Class.new(Model)
|
User = Class.new(Model)
|
||||||
Location = Class.new(Model)
|
Location = Class.new(Model)
|
||||||
Place = Class.new(Model)
|
Place = Class.new(Model)
|
||||||
|
Tag = Class.new(Model)
|
||||||
Comment = Class.new(Model) do
|
Comment = Class.new(Model) do
|
||||||
# Uses a custom non-time-based cache key
|
# Uses a custom non-time-based cache key
|
||||||
def cache_key
|
def cache_key
|
||||||
@ -224,6 +225,12 @@ PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
|
|||||||
belongs_to :author, serializer: AuthorPreviewSerializer
|
belongs_to :author, serializer: AuthorPreviewSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
PostWithTagsSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id
|
||||||
|
|
||||||
|
has_many :tags
|
||||||
|
end
|
||||||
|
|
||||||
Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
|
Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
attributes :id
|
attributes :id
|
||||||
end
|
end
|
||||||
|
|||||||
@ -29,8 +29,10 @@ module ActiveModel
|
|||||||
@author.roles = []
|
@author.roles = []
|
||||||
@blog = Blog.new({ name: 'AMS Blog' })
|
@blog = Blog.new({ name: 'AMS Blog' })
|
||||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||||
|
@tag = Tag.new({name: '#hashtagged'})
|
||||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
|
@post.tags = [@tag]
|
||||||
@post.blog = @blog
|
@post.blog = @blog
|
||||||
@comment.post = @post
|
@comment.post = @post
|
||||||
@comment.author = nil
|
@comment.author = nil
|
||||||
@ -65,6 +67,14 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_has_many_with_no_serializer
|
||||||
|
PostWithTagsSerializer.new(@post).each_association do |name, serializer, options|
|
||||||
|
assert_equal name, :tags
|
||||||
|
assert_equal serializer, nil
|
||||||
|
assert_equal [{ attributes: { name: "#hashtagged" }}].to_json, options[:virtual_value].to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_serializer_options_are_passed_into_associations_serializers
|
def test_serializer_options_are_passed_into_associations_serializers
|
||||||
@post_serializer.each_association do |name, association|
|
@post_serializer.each_association do |name, association|
|
||||||
if name == :comments
|
if name == :comments
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user