我试图不对散列中的字符串进行 jsonify。它已经被转义了。
阅读处理 PORO 的方法是覆盖 as_json
。所以我将字符串包装在另一个对象中。但是当我返回对象时,我只处理一个导致 stack level too deep
的字符串。当我返回已经编码的字符串时,它显然试图转义它。 activesupport-6.0.3.2/lib/active_support/json/encoding.rb
def jsonify(value)
case value
when String
EscapedString.new(value)
when Numeric, NilClass, TrueClass, FalseClass
value.as_json
when Hash
Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
when Array
value.map { |v| jsonify(v) }
else
jsonify value.as_json
end
end
我能做的就是猴子修补上面的方法来接受我包装字符串的类,什么也不做。
我想另一种选择是将 JSON 字符串解析回散列,然后让它遵循正常程序。不过,这会对我们的表现产生太大影响。
所以我的问题是,是否有更优雅的方式告诉 Rails 在遇到指定对象时尝试对它进行 jsonify 处理时什么都不做?
编辑:
我正在使用这个已经 jsonified 的字符串,例如:
{foo: MyStringJsonWrapper.new('{"bar":"foobar"}')}.to_json
最佳答案
我查看了文件 activesupport-6.0.3.2/lib/active_support/json/encoding.rb
并注意到您可以配置哪个类用于执行 json 编码。当前是包含在该类中的 JSONGemEncoder
。
所以我制作了自己的类(class):
class MyJSONEncoder < ActiveSupport::JSON::Encoding::JSONGemEncoder
class AlreadyEscapedString < String
def to_json(*)
self
end
end
private
def jsonify(value)
if value.is_a?(AlreadyEncodedStringWrapper)
AlreadyEscapedString.new(value.already_jsonified)
else
super
end
end
end
和
class AlreadyEncodedStringWrapper
attr_accessor :already_jsonified
def initialize already_jsonified
@already_jsonified = already_jsonified
end
def as_json(options = {})
self
end
end
存在 AlreadyEscapedString
的额外类来覆盖 EscapedString
的行为(在同一编码类中找到)但什么都不做。
然后设置:
ActiveSupport.json_encoder = MyJSONEncoder
例子:
jsonified_hash = {foobar: "barbaz"}.to_json
already_encoded_string = AlreadyEncodedStringWrapper.new(jsonified_hash)
{foo: already_encoded_string}.to_json
=> "{\"foo\": {\"foobar\": \"barbaz\"}}"
关于ruby-on-rails - 停止在哈希 Ruby on Rails 中编码的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63152802/