From 783db25e0c640c1588732967a87d65c10fddc08e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 3 Jul 2009 23:12:42 -0500 Subject: Integrate AMo JSON serializer into AR --- activemodel/lib/active_model/serializer.rb | 60 ++++++++++++++++-------------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'activemodel/lib/active_model/serializer.rb') diff --git a/activemodel/lib/active_model/serializer.rb b/activemodel/lib/active_model/serializer.rb index 7a55921e85..5b603bdbd7 100644 --- a/activemodel/lib/active_model/serializer.rb +++ b/activemodel/lib/active_model/serializer.rb @@ -8,6 +8,9 @@ module ActiveModel def initialize(serializable, options = nil) @serializable = serializable @options = options ? options.dup : {} + + @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s } + @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s } end def serialize @@ -18,37 +21,40 @@ module ActiveModel serialize(&block) end - protected - def serializable_attribute_names - attribute_names = @serializable.attributes.keys - - if options[:only] - only = Array.wrap(options[:only]).map { |n| n.to_s } - attribute_names &= only - elsif options[:except] - except = Array.wrap(options[:except]).map { |n| n.to_s } - attribute_names -= except - end - - attribute_names + # To replicate the behavior in ActiveRecord#attributes, + # :except takes precedence over :only. If :only is not set + # for a N level model but is set for the N+1 level models, + # then because :except is set to a default value, the second + # level model can have both :except and :only set. So if + # :only is set, always delete :except. + def serializable_attribute_names + attribute_names = @serializable.attributes.keys.sort + + if options[:only].any? + attribute_names &= options[:only] + elsif options[:except].any? + attribute_names -= options[:except] end - def serializable_method_names - Array.wrap(options[:methods]).inject([]) do |methods, name| - methods << name if @serializable.respond_to?(name.to_s) - methods - end - end + attribute_names + end - def serializable_names - serializable_attribute_names + serializable_method_names + def serializable_method_names + Array.wrap(options[:methods]).inject([]) do |methods, name| + methods << name if @serializable.respond_to?(name.to_s) + methods end + end - def serializable_hash - serializable_names.inject({}) { |hash, name| - hash[name] = @serializable.send(name) - hash - } - end + def serializable_names + serializable_attribute_names + serializable_method_names + end + + def serializable_hash + serializable_names.inject({}) { |hash, name| + hash[name] = @serializable.send(name) + hash + } + end end end -- cgit v1.2.3