From b2967999aeb424d219393f2e01e88a92f37a78c3 Mon Sep 17 00:00:00 2001 From: Jay Elaraj Date: Sat, 17 Jan 2015 02:12:32 -0500 Subject: ensure `method_missing` called for non-existing methods passed to `ActiveModel::Serialization#serializable_hash` --- activemodel/CHANGELOG.md | 5 +++++ activemodel/lib/active_model/serialization.rb | 2 +- activemodel/test/cases/serialization_test.rb | 25 ++++++++++++++++--------- 3 files changed, 22 insertions(+), 10 deletions(-) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 4961d69d2a..3c1510b31d 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,8 @@ +* Ensure `method_missing` is called for methods passed to + `ActiveModel::Serialization#serializable_hash` that don't exist. + + *Jay Elaraj* + * Add `ActiveModel::Dirty#[attr_name]_previously_changed?` and `ActiveModel::Dirty#[attr_name]_previous_change` to improve access to recorded changes after the model has been saved. diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index 976f50b13e..c06a64c75f 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -107,7 +107,7 @@ module ActiveModel hash = {} attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) } - Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) } + Array(options[:methods]).each { |m| hash[m.to_s] = send(m) } serializable_add_includes(options) do |association, records, opts| hash[association.to_s] = if records.respond_to?(:to_ary) diff --git a/activemodel/test/cases/serialization_test.rb b/activemodel/test/cases/serialization_test.rb index 4ae41aa19c..8d3165cd78 100644 --- a/activemodel/test/cases/serialization_test.rb +++ b/activemodel/test/cases/serialization_test.rb @@ -16,6 +16,14 @@ class SerializationTest < ActiveModel::TestCase instance_values.except("address", "friends") end + def method_missing(method_name, *args) + if method_name == :bar + 'i_am_bar' + else + super + end + end + def foo 'i_am_foo' end @@ -58,23 +66,22 @@ class SerializationTest < ActiveModel::TestCase end def test_method_serializable_hash_should_work_with_methods_option - expected = {"name"=>"David", "gender"=>"male", "foo"=>"i_am_foo", "email"=>"david@example.com"} - assert_equal expected, @user.serializable_hash(methods: [:foo]) + expected = {"name"=>"David", "gender"=>"male", "foo"=>"i_am_foo", "bar"=>"i_am_bar", "email"=>"david@example.com"} + assert_equal expected, @user.serializable_hash(methods: [:foo, :bar]) end def test_method_serializable_hash_should_work_with_only_and_methods - expected = {"foo"=>"i_am_foo"} - assert_equal expected, @user.serializable_hash(only: [], methods: [:foo]) + expected = {"foo"=>"i_am_foo", "bar"=>"i_am_bar"} + assert_equal expected, @user.serializable_hash(only: [], methods: [:foo, :bar]) end def test_method_serializable_hash_should_work_with_except_and_methods - expected = {"gender"=>"male", "foo"=>"i_am_foo"} - assert_equal expected, @user.serializable_hash(except: [:name, :email], methods: [:foo]) + expected = {"gender"=>"male", "foo"=>"i_am_foo", "bar"=>"i_am_bar"} + assert_equal expected, @user.serializable_hash(except: [:name, :email], methods: [:foo, :bar]) end - def test_should_not_call_methods_that_dont_respond - expected = {"name"=>"David", "gender"=>"male", "email"=>"david@example.com"} - assert_equal expected, @user.serializable_hash(methods: [:bar]) + def test_should_raise_NoMethodError_for_non_existing_method + assert_raise(NoMethodError) { @user.serializable_hash(methods: [:nada]) } end def test_should_use_read_attribute_for_serialization -- cgit v1.2.3