Raise NoMethodError in ActiveModel::Type::Value#as_json method.

Right now since we have instance variable called `itself_if_serialize_cast_value_compatible`
assigned to self when we run `as_json` we get stack too deep error because `as_json` calls
`as_json` on every instance variable. And since `@itself_if_serialize_cast_value_compatible` references
to `self` we run into recursion.

And before that we were returning unpredictable data from `as_json` method so it's better to let it to throw
an error and let user know that Value class is not supposed to be converted to json.
This commit is contained in:
Vasiliy Ermolovich 2022-11-20 20:36:29 +01:00
parent 2497eb0d5d
commit 433bd5995d
3 changed files with 16 additions and 0 deletions

@ -1,3 +1,8 @@
* Raise `NoMethodError` in `ActiveModel::Type::Value#as_json` to avoid unpredictable
results.
*Vasiliy Ermolovich*
* Custom attribute types that inherit from Active Model built-in types and do
not override the `serialize` method will now benefit from an optimization
when serializing attribute values for the database.

@ -135,6 +135,10 @@ def immutable_value(value) # :nodoc:
value
end
def as_json(*)
raise NoMethodError
end
private
# Convenience method for types which do not need separate type casting
# behavior for user and database inputs. Called by Value#cast for

@ -1,6 +1,7 @@
# frozen_string_literal: true
require "cases/helper"
require "active_support/core_ext/object/json"
module ActiveModel
module Type
@ -10,6 +11,12 @@ def test_type_equality
assert_not_equal Type::Value.new, Type::Integer.new
assert_not_equal Type::Value.new(precision: 1), Type::Value.new(precision: 2)
end
def test_as_json_not_defined
assert_raises NoMethodError do
Type::Value.new.as_json
end
end
end
end
end