[Ruby]Sheets API v4のupdate_spreadsheet_valueでNameErrorの対処方法(uninitialized constant ActiveSupport::JSON (NameError))

Rubyからスプレッドシートのセル情報を読み書きしたくて、まず公式が提供しているQuickstartを試してみました。
[Ruby Quickstart  |  Sheets API  |  Google Developers](https://developers.google.com/sheets/api/quickstart/ruby)

Quickstartではシートのセル値を取得まであり、セルを更新（値を書き込む）は用意されておりませんでした。

なのでドキュメントやQiitaを参考に試したのですが、エラーが出たためその解決方法を書いていきたいと思います。

SheetsAPIの操作はQuickstartと同じ`google-api-ruby-client`を使用しています。

# `uninitialized constant ActiveSupport::JSON (NameError)`の対処方法
`update_spreadsheet_value`にてセルの更新を行おうとしたときに、`uninitialized constant ActiveSupport::JSON (NameError)`が発生しました。

`google-api-client`の中でto_jsonメソッドが使用されているのですが、to_jsonメソッドはActiveSupportのメソッドであり、ActiveSupportが入っていないことが原因でした。

Gemfileに`gem 'activesupport'`を追記し、`update_spreadsheet_value`を使うファイルに`require 'active_support'`を追記することでエラーを解消できました。

<font color="FireBrick">2020年8月11日追記: `require 'json'`でも大丈夫っぽいです。既存アプリで確認したのですが、そもそも読み込まなくても発生しなくなってしまったので原因がわからなくなりました。。。</font>

```ruby:Gemfile
...

gem 'google-api-client'
gem 'activesupport'

```

```ruby:sample.rb
require 'google/apis/sheets_v4'
require 'active_support' # active_supportを読み込む

def updated_cells(values)
  spreadsheet_id = 'xxxxxxxxx'
  value_range_object = Google::Apis::SheetsV4::ValueRange.new(values: values)
  range = 'sheet!D2:D'
  result = service.update_spreadsheet_value(
    spreadsheet_id,
    range,
    value_range_object,
    value_input_option: 'RAW'
  )
  puts "#{result.updated_cells} cells updated."
end
```

## 実際のエラー内容
実際のエラーはこのような内容でした。

```
Traceback (most recent call last):
	11: from main.rb:25:in `<main>'
	10: from main.rb:12:in `main'
	 9: from /myapp/src/sheets.rb:32:in `write_price'
	 8: from /usr/local/bundle/gems/google-api-client-0.42.2/generated/google/apis/sheets_v4/service.rb:787:in `update_spreadsheet_value'
	 7: from /usr/local/bundle/gems/google-api-client-0.42.2/lib/google/apis/core/base_service.rb:360:in `execute_or_queue_command'
	 6: from /usr/local/bundle/gems/google-api-client-0.42.2/lib/google/apis/core/http_command.rb:99:in `execute'
	 5: from /usr/local/bundle/gems/google-api-client-0.42.2/lib/google/apis/core/api_command.rb:66:in `prepare!'
	 4: from /usr/local/bundle/gems/representable-3.0.4/lib/representable/json.rb:44:in `to_json'
	 3: from /usr/local/bundle/gems/multi_json-1.15.0/lib/multi_json.rb:139:in `dump'
	 2: from /usr/local/bundle/gems/multi_json-1.15.0/lib/multi_json/adapter.rb:25:in `dump'
	 1: from /usr/local/bundle/gems/multi_json-1.15.0/lib/multi_json/adapters/json_common.rb:19:in `dump'
/usr/local/bundle/gems/activesupport-6.0.3.2/lib/active_support/core_ext/object/json.rb:42:in `to_json': uninitialized constant ActiveSupport::JSON (NameError)
```


# 実際に使用したファイル
実際に使用したファイルを参考に載せておきます。

```ruby:sheets.rb
require "google/apis/sheets_v4"
require "googleauth"
require "googleauth/stores/file_token_store"
require "fileutils"
require 'active_support'

class Sheets
  OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
  APPLICATION_NAME = 'Sample App'.freeze
  CREDENTIALS_PATH = 'credentials.json'.freeze
  TOKEN_PATH = 'token.yaml'.freeze
  SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS
  SPREADSHEET_ID = 'xxxxxxxxxxxxxxxxxx'.freeze

  attr_reader :service

  def initialize
    @service = setup_service
  end

  def symbols
    range = 'sheet!C2:C'
    response = service.get_spreadsheet_values(SPREADSHEET_ID, range)
    puts 'No data found.' if response.values.empty?

    response.values.flatten
  end

  def update_price_cells(values)
    value_range_object = Google::Apis::SheetsV4::ValueRange.new(values: values)
    range = 'sheet!D2:D'
    result = service.update_spreadsheet_value(
      SPREADSHEET_ID,
      range,
      value_range_object,
      value_input_option: 'RAW'
    )
    puts "#{result.updated_cells} cells updated."
  end

  private

    def setup_service
      service = Google::Apis::SheetsV4::SheetsService.new
      service.client_options.application_name = APPLICATION_NAME
      service.authorization = authorize
      service
    end

    def authorize
      client_id = Google::Auth::ClientId.from_file(CREDENTIALS_PATH)
      token_store = Google::Auth::Stores::FileTokenStore.new(file: TOKEN_PATH)
      authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
      user_id = 'default'
      credentials = authorizer.get_credentials(user_id)
      if credentials.nil?
        url = authorizer.get_authorization_url(base_url: OOB_URI)
        puts 'Open the following URL in the browser and enter the ' \
             "resulting code after authorization:\n" + url
        code = gets
        credentials = authorizer.get_and_store_credentials_from_code(
          user_id: user_id, code: code, base_url: OOB_URI
        )
      end
      credentials
    end
end

```

# まとめ
Railsを書いているときに何気なく書いていた`to_json`はActiveSupportのメソッドだということを知り勉強になりました。
ActiveSupportは様々なgemで使用されているようです。

なにかわからない部分などありましたら、質問やコメント、[Twitter](https://twitter.com/_necocoa)にてお願いします。