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'
でも大丈夫っぽいです。既存アプリで確認したのですが、そもそも読み込まなくても発生しなくなってしまったので原因がわからなくなりました。。。
...
gem 'google-api-client'
gem 'activesupport'
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)
実際に使用したファイル
実際に使用したファイルを参考に載せておきます。
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にてお願いします。