0

RestClient を介してバックエンド データ ストア (レールではなくルビー) に接続するレール アプリに取り組んでいます。このメソッドを Rails アプリのバックエンド API クラスに追加して、バックエンドからファイル サイズを取得しました。

class Backend < ActiveResource::Base
  def self.file_size(file_key)
    RestClient.get("#{SERVER_URL}/files/#{file_key}/size")
  end
end

バックエンドの対応するコードは次のとおりです。

get '/files/:file_id/size' do
  json_for file.size
end

サンプル ファイルの場合、Backend.file_size(file.key) は「198942」を返しますが、この属性がデータベースに (整数フィールドで) 保存されると、200 として int にキャストされます。

Railsコンソール内でこれを少し試してみましたが、出力は混乱しています。

test_size = Backend.file_size(file.key)
=> "198942"
control_size = "198942"
=> "198942"

test_size.class
=> String
control_size.class
=> String

test_size.bytes.to_a
=> [49, 57, 56, 57, 52, 50]
control_size.bytes.to_a
=> [49, 57, 56, 57, 52, 50]

test_size.to_i
=> 200
control_size.to_i
=> 198942

Integer(test_size)
=> 198942
Integer(control_size)
=> 198942

test_size.to_s.to_i
=> 200
control_size.to_s.to_i
=> 198942

test_size.tr('^A-Za-z0-9', '').to_i
=> 198942

エンコーディングも確認したところ、残りの応答は US-ASCII でしたが、force_encoded を UTF-8 にすると動作は同じでした。奇妙なことに、test_size は Integer と tr サブの下で正しくキャストして非表示文字を削除しますが、バイトの内容は制御文字列と同じです。

私は最終的にこの質問の根源にたどり着きました(以下で回答)が、誰かが以前にこの経験をしたことがあるかどうか、そして誰かがRestClientがこのように応答する理由(この特定の場合)について洞察を持っているかどうかに興味があります.

4

1 に答える 1

3

さらに調査した結果 (test_size と control_size のパブリック メソッドを調べて)、RestClient からの戻り値が RestClient::Response であることを発見しました。

test_size.is_a?(String)
=> true
test_size.is_a?(RestClient::Response)
=> true

test_size.code
=> 200

これは非常に予想外の動作だと思います (ただし、JSON の代わりに残りのクライアントを介して裸の値を送信することはやや珍しいことはわかっています)。 String として明示され、モンキーが多数の String メソッドにパッチを適用したように見えるハイブリッド オブジェクト (ただし、すべてではない - などtr)。

フロントエンドとバックエンドの API クラスをリファクタリングして JSON オブジェクトを渡すだけで、この問題を解決しました。

フロントエンドのリファクタリングされたコード:

class Backend < ActiveResource::Base
  def self.file_size(file_key)
    JSON.parse(RestClient.get("#{SERVER_URL}/files/#{file_key}/size"))
  end
end

バックエンド コード:

get '/files/:file_id/size' do
  json_for file.size
end

class File
  def size
    {
      size: size
    }
  end
end
于 2013-11-15T00:58:44.733 に答える