LoginSignup
2
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-30

Rubyからスプレッドシートのセル情報を読み書きしたくて、まず公式が提供しているQuickstartを試してみました。
Ruby Quickstart  |  Sheets API  |  Google Developers

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'を追記することでエラーを解消できました。

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

Gemfile
...

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

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)

実際に使用したファイル

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

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にてお願いします。

2
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
2
0