Skip to content

Commit

Permalink
serialize_ids call methods on the corresponding serializer if defined
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed May 24, 2013
1 parent ee846f3 commit 9521e91
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 12 deletions.
7 changes: 1 addition & 6 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,7 @@ def include!(name, options={})
association = association_class.new(name, options, self.options)

if association.embed_ids?
node[association.key] =
if options[:embed_key] || self.respond_to?(name) || !self.object.respond_to?(association.id_key)
association.serialize_ids
else
self.object.read_attribute_for_serialization(association.id_key)
end
node[association.key] = association.serialize_ids

if association.embed_in_root? && hash.nil?
raise IncludeError.new(self.class, association.name)
Expand Down
24 changes: 18 additions & 6 deletions lib/active_model/serializer/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def initialize(name, options={}, serializer_options={})
@embed_in_root = options[:include]

serializer = options[:serializer]
@serializer = serializer.is_a?(String) ? serializer.constantize : serializer
@serializer_class = serializer.is_a?(String) ? serializer.constantize : serializer

@options = options
@serializer_options = serializer_options
Expand All @@ -59,11 +59,11 @@ def key

private

attr_reader :embed_key, :serializer, :options, :serializer_options
attr_reader :embed_key, :serializer_class, :options, :serializer_options

def find_serializable(object)
if serializer
serializer.new(object, serializer_options)
if serializer_class
serializer_class.new(object, serializer_options)
elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer)
ams.new(object, serializer_options)
else
Expand Down Expand Up @@ -94,7 +94,12 @@ def serialize

def serialize_ids
object.map do |item|
item.read_attribute_for_serialization(embed_key)
serializer = find_serializable(item)
if serializer.respond_to?(embed_key)
serializer.send(embed_key)
else
item.read_attribute_for_serialization(embed_key)
end
end
end
end
Expand Down Expand Up @@ -143,7 +148,14 @@ def serialize

def serialize_ids
if object
id = object.read_attribute_for_serialization(embed_key)
serializer = find_serializable(object)
id =
if serializer.respond_to?(embed_key)
serializer.send(embed_key)
else
object.read_attribute_for_serialization(embed_key)
end

if polymorphic?
{
:type => polymorphic_key,
Expand Down
69 changes: 69 additions & 0 deletions test/serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,39 @@ def comments
}, json)
end

def test_methods_take_priority_over_associations_and_call_the_appropriate_id_method
comment_serializer = Class.new(ActiveModel::Serializer) do
def id
"OMG"
end
end

post_serializer = Class.new(ActiveModel::Serializer) do
attributes :title
has_many :comments, :serializer => comment_serializer
embed :ids

def comments
object.comments[0,1]
end
end

post = Post.new(:title => "My Post")
comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
post.comments = comments

post.class_eval do
define_method :comment_ids, lambda {
self.comments.map { |c| c.read_attribute_for_serialization(:id) }
}
end
json = post_serializer.new(post).as_json
assert_equal({
:title => "My Post",
:comment_ids => ["OMG"]
}, json)
end

def test_embed_objects
serializer = post_serializer

Expand Down Expand Up @@ -684,6 +717,42 @@ def test_embed_id_for_has_one
}, hash.as_json)
end

def test_embed_id_for_has_one_overriding_associated_id
author_serializer = Class.new(ActiveModel::Serializer) do
def id
"OMG"
end
end

serializer_class = Class.new(ActiveModel::Serializer) do
embed :ids
root :post

attributes :title, :body
has_one :author, :serializer => author_serializer
end

post_class = Class.new(Model) do
attr_accessor :author
end

author_class = Class.new(Model)

post = post_class.new(:title => "New Post", :body => "It's a new post!")
author = author_class.new(:id => 5)
post.author = author

hash = serializer_class.new(post)

assert_equal({
:post => {
:title => "New Post",
:body => "It's a new post!",
:author_id => "OMG"
}
}, hash.as_json)
end

def test_embed_objects_for_has_one
author_serializer = Class.new(ActiveModel::Serializer) do
attributes :id, :name
Expand Down

0 comments on commit 9521e91

Please sign in to comment.