0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JSON.parseからinstanceを作りたいとき

Posted at

これ何

API Clientを作っていた時にresponseを抽象化したclassを作りたかった。その作業メモ

問題

例えば、モンスターを扱うAPIがあったとする。
API Clientは返って来たデータをMonster classで扱いたいはずだ。

class Monster
  def initialize(name:, power:, hp:)
    @name = name; @power = power; @hp = hp
  end
end

そして、次のようなApiClientを利用しているとする。
すると、Monster classを利用すると、ArgumentErrorになってしまう。

Class ApiClient
  def initialize
    @conn = Faraday.new(:url => 'url')
    @base = 'api/v1/'
    @token = ENV['TOKEN']
  end

  def get
    @conn.post "#{@base}monster", {token: @token}.to_json
    monsters = JSON.parse(response.body)
    monsters.each do |monster|
      Monster.new(monster)
      # => ArgumentError: wrong number of arguments (given 1, expected 0)
    end
  end
end

原因

なぜArgumentErrorを起こすのだろうか?
理由は簡単で、initializeしようとしているargumentを見るとわかる。
次のようなstring hashになっているため、keyward引数として渡すことができないのである。

{
  "name": "gerugeru",
  "power": 100,
  "hp": 70
}

解決策

どうすれば良いか、原因は先ほど述べたようにstring hashになっているため、引数に出来なのである。
返ってきた値をJSON.parseする時にsymbol hashにすれば、keyword引数を渡すことができ、instanceを作成することができる。

JSON.parseの引数に、 symbolize_names: true とすることでsymbol hashを扱うことができる

monsters = JSON.parse(response.body, symbolize_names: true)
# => {
#  :name => "gerugeru",
#  :power => 100,
#  :hp => 70
# }

この結果initializerにsymbol hashを渡すことができ、めでたくレスポンスをinstanceとして作成することができた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?