diff options
-rw-r--r-- | activemodel/lib/active_model/serialization.rb | 25 | ||||
-rw-r--r-- | activemodel/test/cases/serialization_test.rb | 6 | ||||
-rw-r--r-- | activemodel/test/cases/serializers/json_serialization_test.rb | 10 | ||||
-rw-r--r-- | activeresource/lib/active_resource/base.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/json/encoding.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/generators/actions.rb | 2 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 8 |
7 files changed, 47 insertions, 12 deletions
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index a756b9f205..7bc3f997b5 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -78,7 +78,8 @@ module ActiveModel attribute_names -= Array.wrap(except).map(&:to_s) end - hash = attributes.slice(*attribute_names) + hash = {} + attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) } method_names = Array.wrap(options[:methods]).select { |n| respond_to?(n) } method_names.each { |n| hash[n] = send(n) } @@ -95,13 +96,33 @@ module ActiveModel end private + + # Hook method defining how an attribute value should be retrieved for + # serialization. By default this is assumed to be an instance named after + # the attribute. Override this method in subclasses should you need to + # retrieve the value for a given attribute differently: + # + # class MyClass + # include ActiveModel::Validations + # + # def initialize(data = {}) + # @data = data + # end + # + # def read_attribute_for_serialization(key) + # @data[key] + # end + # end + # + alias :read_attribute_for_serialization :send + # Add associations specified via the <tt>:include</tt> option. # # Expects a block that takes as arguments: # +association+ - name of the association # +records+ - the association record(s) to be serialized # +opts+ - options for the association records - def serializable_add_includes(options = {}) + def serializable_add_includes(options = {}) #:nodoc: return unless include = options[:include] unless include.is_a?(Hash) diff --git a/activemodel/test/cases/serialization_test.rb b/activemodel/test/cases/serialization_test.rb index 29bcdeae67..1ec915d245 100644 --- a/activemodel/test/cases/serialization_test.rb +++ b/activemodel/test/cases/serialization_test.rb @@ -77,12 +77,12 @@ class SerializationTest < ActiveModel::TestCase assert_equal expected , @user.serializable_hash(:methods => [:bar]) end - def test_should_not_call_methods_for_attributes - def @user.name + def test_should_use_read_attribute_for_serialization + def @user.read_attribute_for_serialization(n) "Jon" end - expected = { "name" => "David" } + expected = { "name" => "Jon" } assert_equal expected, @user.serializable_hash(:only => :name) end diff --git a/activemodel/test/cases/serializers/json_serialization_test.rb b/activemodel/test/cases/serializers/json_serialization_test.rb index 40fdcf20ca..a754d610b9 100644 --- a/activemodel/test/cases/serializers/json_serialization_test.rb +++ b/activemodel/test/cases/serializers/json_serialization_test.rb @@ -206,4 +206,14 @@ class JsonSerializationTest < ActiveModel::TestCase assert_no_match %r{"preferences":}, json end + test "custom as_json options should be extendible" do + def @contact.as_json(options = {}); super(options.merge(:only => [:name])); end + json = @contact.to_json + + assert_match %r{"name":"Konata Izumi"}, json + assert_no_match %r{"created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}}, json + assert_no_match %r{"awesome":}, json + assert_no_match %r{"preferences":}, json + end + end diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 1ffd83b91d..03c4cc5b9e 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -1384,6 +1384,10 @@ module ActiveResource private + def read_attribute_for_serialization(n) + attributes[n] + end + # Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1 def response_code_allows_body?(c) !((100..199).include?(c) || [204,304].include?(c)) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 67698c1cff..469ae69258 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -38,7 +38,7 @@ module ActiveSupport attr_reader :options def initialize(options = nil) - @options = options + @options = options || {} @seen = Set.new end @@ -59,7 +59,7 @@ module ActiveSupport def options_for(value) if value.is_a?(Array) || value.is_a?(Hash) # hashes and arrays need to get encoder in the options, so that they can detect circular references - (options || {}).merge(:encoder => self) + options.merge(:encoder => self) else options end diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 5af5d3b856..b26839644e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -90,7 +90,7 @@ module Rails append_file "Gemfile", "\ngroup #{name} do\n", :force => true @in_group = true - instance_eval &block + instance_eval(&block) @in_group = false append_file "Gemfile", "end\n", :force => true diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 448982f9de..97ad47ac14 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -306,7 +306,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") end @@ -319,7 +319,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors") end @@ -332,7 +332,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") end @@ -345,7 +345,7 @@ module ApplicationTests require "#{app_path}/config/environment" require "mail" - ActionMailer::Base + _ = ActionMailer::Base assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers") end |