mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Merge pull request #198 from jredburn/master
'embed_key' option to allow embedding by attributes other than IDs
This commit is contained in:
commit
dc2257977f
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
|
||||
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
|
||||
|
||||
@ -103,6 +103,14 @@ module ActiveModel
|
||||
end
|
||||
end
|
||||
|
||||
def embed_key
|
||||
if key = option(:embed_key)
|
||||
key
|
||||
else
|
||||
:id
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
associated_object.map do |item|
|
||||
find_serializable(item).serializable_hash
|
||||
@ -120,11 +128,11 @@ module ActiveModel
|
||||
# return collection.ids if collection.respond_to?(: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)
|
||||
else
|
||||
associated_object.map do |item|
|
||||
item.read_attribute_for_serialization(:id)
|
||||
item.read_attribute_for_serialization(embed_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -163,6 +171,14 @@ module ActiveModel
|
||||
end
|
||||
end
|
||||
|
||||
def embed_key
|
||||
if key = option(:embed_key)
|
||||
key
|
||||
else
|
||||
:id
|
||||
end
|
||||
end
|
||||
|
||||
def polymorphic_key
|
||||
associated_object.class.to_s.demodulize.underscore.to_sym
|
||||
end
|
||||
@ -191,15 +207,15 @@ module ActiveModel
|
||||
if associated_object
|
||||
{
|
||||
:type => polymorphic_key,
|
||||
:id => associated_object.read_attribute_for_serialization(:id)
|
||||
:id => associated_object.read_attribute_for_serialization(embed_key)
|
||||
}
|
||||
else
|
||||
nil
|
||||
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")
|
||||
elsif associated_object
|
||||
associated_object.read_attribute_for_serialization(:id)
|
||||
associated_object.read_attribute_for_serialization(embed_key)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
@ -34,12 +34,12 @@ class AssociationTest < ActiveModel::TestCase
|
||||
@root_hash = {}
|
||||
|
||||
@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.comment = @comment
|
||||
|
||||
@comment_serializer_class = def_serializer do
|
||||
attributes :id, :body
|
||||
attributes :id, :external_id, :body
|
||||
end
|
||||
|
||||
@post_serializer_class = def_serializer do
|
||||
@ -75,7 +75,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -105,7 +105,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
}, @hash)
|
||||
|
||||
assert_equal({
|
||||
:comments => [{ :id => 1, :body => "ZOMG A COMMENT" }]
|
||||
:comments => [{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }]
|
||||
}, @root_hash)
|
||||
end
|
||||
end
|
||||
@ -124,7 +124,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -142,7 +142,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -160,7 +160,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -178,7 +178,79 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
: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)
|
||||
end
|
||||
@ -192,7 +264,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @hash)
|
||||
|
||||
@ -237,7 +309,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -280,7 +352,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
|
||||
assert_equal({
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, @root_hash)
|
||||
end
|
||||
@ -336,7 +408,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
:comment_ids => [ 1 ]
|
||||
},
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, json)
|
||||
end
|
||||
@ -387,7 +459,7 @@ class AssociationTest < ActiveModel::TestCase
|
||||
:comment_ids => [ 1 ]
|
||||
},
|
||||
:comments => [
|
||||
{ :id => 1, :body => "ZOMG A COMMENT" }
|
||||
{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
|
||||
]
|
||||
}, json)
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user