ActiveSupport::JSON(to_json/as_json)
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/json/encoding.rb
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/core_ext/object/json.rb
https://abicky.net/2017/05/07/180842/
ActiveSupportでto_jsonが上書きされており、ActiveSupport::JSON.encodeを呼び出すようになっている
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/core_ext/object/json.rb#L42
ActiveSupport::JSON.encodeはActiveSupport::JSON::Encoding.json_encoderに処理を委譲している
デフォルトは同じファイルで定義されているJSONGemEncoder
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/json/encoding.rb#L26
json_encoder=を使ってエンコーダーを差し替えることができる
Ojの場合Oj.optimize_railsを実行するとOj::Rails::Encoderに差し替えられる
https://www.rubydoc.info/gems/oj/Oj.optimize_rails
時刻(Timeオブジェクト)の扱い
ActiveSupport::JSON::Encoding.use_standard_json_time_formatがtrueであればISO8601形式の文字列に変換される(デフォルトはtrue)
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/core_ext/object/json.rb#L178
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/json/encoding.rb#L128
Time#xmlschemaはiso8601のalias
https://docs.ruby-lang.org/ja/2.7.0/method/Time/i/iso8601.html
ActiveSupport::JSON::Encoding.time_precision=で小数点以下の桁数も変更できる(デフォルトは3)
false であればstrftime("%Y/%m/%d %H:%M:%S %z")する
JSONGemEncoder
encodeではstringify jsonify value.as_json(options.dup)を実行する
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/json/encoding.rb#L35
jsonifyではクラスでcase whenして再帰的にas_jsonを呼び出している
Stringの場合EscapedString.new(value)している
https://github.com/rails/rails/blob/v6.0.3.2/activesupport/lib/active_support/json/encoding.rb#L54
Encoding.escape_html_entities_in_jsonが
falseのときは\u2028, \u2029を、
trueのときはそれに加えて>, <, &をUnicodeエスケープする(デフォルトはtrue)
JavaScriptやHTMLに埋め込んだときに不正になってしまうのを避けるためらしい
手元のRailsアプリで><&がエスケープされなくてなんでや…と思ってたらOj.mimic_JSONしてるとだめっぽい
Oj.mimic_JSONしているならOj.optimize_railsも実行しておこう(Oj::Rails::Encoderならうまくいく)
#Rails