2

Rails コントローラーの呼び出しに対して JSON を返しています。コントローラーでは、NaN オブジェクトを含む Ruby ハッシュから JSON を生成する必要があります。JSON が返されると、ブラウザーにエラーが表示されます。

{
  "value": NaN
}

エラー: 1 行目の解析エラー: "値": NaN

簡単な調査を行ったところ、NaN は有効な JSON オブジェクトではないため、引用符で囲む必要があるようです - 「NaN」。Rails の JSON パーサーが標準の JSON 形式に準拠しておらず、NaN オブジェクトを引用符で囲んでいるというのは、かなりばかげているように思えます。

ハッシュを文字列にフラット化し、ハッシュに変換しようとしました。しかし、一貫して解析エラーが発生しています。

どうすればこれを回避できますか?


編集:

問題を単純化すると、ハッシュは次のようになります。

{ "value" => Float::NAN }

編集2:

上記のハッシュを次の json に変換する必要があります。

{
  "value": "NaN"
}
4

5 に答える 5

5

ああ、私はそれを理解しました-これは約10か月前にRailsメインブランチで修正されました. (https://github.com/rails/rails/commit/7b53d1372df4bbc7a539b5e493ff1491ec460397)

Rails 3.2.3 < で修正するには、次のコードを追加するだけです。

class Float
  def as_json(options = nil) finite? ? self : NilClass::AS_JSON end #:nodoc:
end
于 2012-06-18T22:45:03.380 に答える
2

私は同様の問題に遭遇し、Rails 3.2.8 を使用しているにもかかわらず、Brian のコメント (NilClass::AS_JSON が未定義であるというエラーを通じて、彼が提案したコード スニペットも) に従って問題を修正することができませんでした。

しかし、私はこの興味深い議論を見つけました:

https://github.com/flori/json/pull/145

これは、to_json / parse は、ネットワーク経由で通信する場合など、言語間の互換性に優れていることを示しているようですが、JSON.dump / JSON.load は、Ruby でのみ動作する場合により良い結果を提供します。

to_json/parse の代わりに dump/load を使用すると、NaN を含むハッシュをシリアライズおよびデシリアライズする機能が修正されることがわかりました。

于 2012-09-20T14:46:08.393 に答える
2

甘いものをチェックしてくださいActiveModel::Serializer(現在はレールにバンドルされています)。これにより、コントローラーがモデルをシリアル化する方法をカスタマイズできます。

class Blark < ActiveRecord::Base
  attr_accessor :value
end

class BlarkSerializer < ActiveModel::Serializer
  attributes :value
  def value
    (@bject.value.is_a?(Float) && @object.value.nan?) ? "NaN" : @object.value
  end
end

警告

これは、コントローラーのrenderメソッドでのみ機能します。Rails コンソールで動作するとは思わないでください。私は、メソッドをそのメソッドで上書きする簡単で汚いモジュールActiveModel::Serializersを持っているActiveModel::Serializerので、物事はもう少し一貫しています。

于 2012-06-18T22:32:34.183 に答える
0

このハックはレールを必要とせず、vanilla 2.2.x ruby​​ で動作しますが、以下のように「ensure」ブロックを含めるように注意してください。(適切に) 警告が表示される可能性があるため、注意して使用してください。

begin
  tmp = Float::NAN
  Float::NAN = 'NaN'
  { "value" => Float::NAN }.to_json
ensure
  Float::NAN = tmp
end
于 2016-05-19T20:54:54.967 に答える