mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Adding 'embed_key' option to allow embedding attributes other than ID
This commit is contained in:
parent
d638e21c8c
commit
7cd7d295e0
28
README.md
28
README.md
@ -535,6 +535,34 @@ This would generate JSON that would look like this:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also specify a different attribute to use rather than the ID of the
|
||||||
|
objects:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
embed :ids, :include => true
|
||||||
|
|
||||||
|
attributes :id, :title, :body
|
||||||
|
has_many :comments, :embed_key => :external_id
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This would generate JSON that would look like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"post": {
|
||||||
|
"id": 1,
|
||||||
|
"title": "New post",
|
||||||
|
"body": "A body!",
|
||||||
|
"comment_ids": [ "COMM001" ]
|
||||||
|
},
|
||||||
|
"comments": [
|
||||||
|
{ "id": 1, "external_id": "COMM001", "body": "what a dumb post" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**NOTE**: The `embed :ids` mechanism is primary useful for clients that process
|
**NOTE**: The `embed :ids` mechanism is primary useful for clients that process
|
||||||
data in bulk and load it into a local store. For these clients, the ability to
|
data in bulk and load it into a local store. For these clients, the ability to
|
||||||
easily see all of the data per type, rather than having to recursively scan the
|
easily see all of the data per type, rather than having to recursively scan the
|
||||||
|
|||||||
@ -103,6 +103,14 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def embed_key
|
||||||
|
if key = option(:embed_key)
|
||||||
|
key
|
||||||
|
else
|
||||||
|
:id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def serialize
|
def serialize
|
||||||
associated_object.map do |item|
|
associated_object.map do |item|
|
||||||
find_serializable(item).serializable_hash
|
find_serializable(item).serializable_hash
|
||||||
@ -120,11 +128,11 @@ module ActiveModel
|
|||||||
# return collection.ids if collection.respond_to?(:ids)
|
# return collection.ids if collection.respond_to?(:ids)
|
||||||
ids_key = "#{key.to_s.singularize}_ids"
|
ids_key = "#{key.to_s.singularize}_ids"
|
||||||
|
|
||||||
if !option(:include) && source_serializer.object.respond_to?(ids_key)
|
if !option(:include) && !option(:embed_key) && source_serializer.object.respond_to?(ids_key)
|
||||||
source_serializer.object.send(ids_key)
|
source_serializer.object.send(ids_key)
|
||||||
else
|
else
|
||||||
associated_object.map do |item|
|
associated_object.map do |item|
|
||||||
item.read_attribute_for_serialization(:id)
|
item.read_attribute_for_serialization(embed_key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -163,6 +171,14 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def embed_key
|
||||||
|
if key = option(:embed_key)
|
||||||
|
key
|
||||||
|
else
|
||||||
|
:id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def polymorphic_key
|
def polymorphic_key
|
||||||
associated_object.class.to_s.demodulize.underscore.to_sym
|
associated_object.class.to_s.demodulize.underscore.to_sym
|
||||||
end
|
end
|
||||||
@ -191,15 +207,15 @@ module ActiveModel
|
|||||||
if associated_object
|
if associated_object
|
||||||
{
|
{
|
||||||
:type => polymorphic_key,
|
:type => polymorphic_key,
|
||||||
:id => associated_object.read_attribute_for_serialization(:id)
|
:id => associated_object.read_attribute_for_serialization(embed_key)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
elsif source_serializer.object.respond_to?("#{name}_id")
|
elsif !option(:embed_key) && source_serializer.object.respond_to?("#{name}_id")
|
||||||
source_serializer.object.send("#{name}_id")
|
source_serializer.object.send("#{name}_id")
|
||||||
elsif associated_object
|
elsif associated_object
|
||||||
associated_object.read_attribute_for_serialization(:id)
|
associated_object.read_attribute_for_serialization(embed_key)
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|||||||
@ -34,12 +34,12 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
@root_hash = {}
|
@root_hash = {}
|
||||||
|
|
||||||
@post = Model.new(:title => "New Post", :body => "Body")
|
@post = Model.new(:title => "New Post", :body => "Body")
|
||||||
@comment = Model.new(:id => 1, :body => "ZOMG A COMMENT")
|
@comment = Model.new(:id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT")
|
||||||
@post.comments = [ @comment ]
|
@post.comments = [ @comment ]
|
||||||
@post.comment = @comment
|
@post.comment = @comment
|
||||||
|
|
||||||
@comment_serializer_class = def_serializer do
|
@comment_serializer_class = def_serializer do
|
||||||
attributes :id, :body
|
attributes :id, :external_id, :body
|
||||||
end
|
end
|
||||||
|
|
||||||
@post_serializer_class = def_serializer do
|
@post_serializer_class = def_serializer do
|
||||||
@ -75,7 +75,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -105,7 +105,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
}, @hash)
|
}, @hash)
|
||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [{ :id => 1, :body => "ZOMG A COMMENT" }]
|
:comments => [{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -124,7 +124,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -142,7 +142,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -160,7 +160,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -178,7 +178,79 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
|
]
|
||||||
|
}, @root_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_with_default_has_many_with_custom_embed_key
|
||||||
|
@post_serializer_class.class_eval do
|
||||||
|
has_many :comments, :embed_key => :external_id
|
||||||
|
end
|
||||||
|
|
||||||
|
include! :comments
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comment_ids => [ "COMM001" ]
|
||||||
|
}, @hash)
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comments => [
|
||||||
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
|
]
|
||||||
|
}, @root_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_with_default_has_one_with_custom_embed_key
|
||||||
|
@post_serializer_class.class_eval do
|
||||||
|
has_one :comment, :embed_key => :external_id
|
||||||
|
end
|
||||||
|
|
||||||
|
include! :comment
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comment_id => "COMM001"
|
||||||
|
}, @hash)
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comments => [
|
||||||
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
|
]
|
||||||
|
}, @root_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_with_default_has_many_with_custom_key_and_custom_embed_key
|
||||||
|
@post_serializer_class.class_eval do
|
||||||
|
has_many :comments, :key => :custom_comments, :embed_key => :external_id
|
||||||
|
end
|
||||||
|
|
||||||
|
include! :comments
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:custom_comments => [ "COMM001" ]
|
||||||
|
}, @hash)
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comments => [
|
||||||
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
|
]
|
||||||
|
}, @root_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_with_default_has_one_with_custom_key_and_custom_embed_key
|
||||||
|
@post_serializer_class.class_eval do
|
||||||
|
has_one :comment, :key => :custom_comment, :embed_key => :external_id
|
||||||
|
end
|
||||||
|
|
||||||
|
include! :comment
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:custom_comment => "COMM001"
|
||||||
|
}, @hash)
|
||||||
|
|
||||||
|
assert_equal({
|
||||||
|
:comments => [
|
||||||
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -192,7 +264,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @hash)
|
}, @hash)
|
||||||
|
|
||||||
@ -237,7 +309,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -280,7 +352,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, @root_hash)
|
}, @root_hash)
|
||||||
end
|
end
|
||||||
@ -336,7 +408,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
:comment_ids => [ 1 ]
|
:comment_ids => [ 1 ]
|
||||||
},
|
},
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, json)
|
}, json)
|
||||||
end
|
end
|
||||||
@ -387,7 +459,7 @@ class AssociationTest < ActiveModel::TestCase
|
|||||||
:comment_ids => [ 1 ]
|
:comment_ids => [ 1 ]
|
||||||
},
|
},
|
||||||
:comments => [
|
:comments => [
|
||||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||||
]
|
]
|
||||||
}, json)
|
}, json)
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user