Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor to make way for easy feature adding #1111

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 60 additions & 26 deletions lib/active_model/serializer/adapter/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,16 @@ class Adapter
class Json < Adapter
def serializable_hash(options = nil)
options ||= {}

if serializer.respond_to?(:each)
@result = serializer.map { |s| FlattenJson.new(s).serializable_hash(options) }
@result = serialize_array_without_root(serializer, options)
else
@hash = {}

@core = cache_check(serializer) do
serializer.attributes(options)
end
@core = resource_object_for(serializer, options)

add_resource_relationships(serializer)

serializer.associations.each do |association|
serializer = association.serializer
opts = association.options

if serializer.respond_to?(:each)
array_serializer = serializer
@hash[association.key] = array_serializer.map do |item|
cache_check(item) do
item.attributes(opts)
end
end
else
@hash[association.key] =
if serializer && serializer.object
cache_check(serializer) do
serializer.attributes(options)
end
elsif opts[:virtual_value]
opts[:virtual_value]
end
end
end
@result = @core.merge @hash
end

Expand All @@ -47,6 +26,61 @@ def fragment_cache(cached_hash, non_cached_hash)
Json::FragmentCache.new().fragment_cache(cached_hash, non_cached_hash)
end

private

# iterate through the associations on the serializer,
# adding them to @hash as needed (as singular or plural)
def add_resource_relationships(serializer)
serializer.associations.each do |association|
serializer = association.serializer
opts = association.options

if serializer.respond_to?(:each)
add_has_many_relationship(association.key, serializer, opts)
else
add_singular_relationship(association.key, serializer, opts)
end
end

@hash
end

# add a singular relationship
def add_singular_relationship(key, serializer, options)
@hash[key] = serialized_or_virtual_of(serializer, options)
end

# add a many relationship
def add_has_many_relationship(key, serializer, options)
@hash[key] = serialize_array(serializer, options)
end

def serialize_array_without_root(serializer, options)
serializer.map { |s| FlattenJson.new(s).serializable_hash(options) }
end

# a virtual value is something that doesn't need a serializer,
# such as a ruby array, or any other raw value
def serialized_or_virtual_of(serializer, options)
if serializer && serializer.object
resource_object_for(serializer, options)
elsif options[:virtual_value]
options[:virtual_value]
end
end

def serialize_array(serializer, options)
serializer.map do |item|
resource_object_for(item, options)
end
end

def resource_object_for(item, options)
cache_check(item) do
item.attributes(options)
end
end

end
end
end
Expand Down