This catches exceptions that can happen when an authentication is expired or removed by the user on google's side.
82 lines
2.8 KiB
Ruby
82 lines
2.8 KiB
Ruby
require 'google/apis/sheets_v4'
|
|
class Form < ApplicationRecord
|
|
# Hash to translate an index to a A1 notation. e.g. 1 => 'B', 27 => 'AA'
|
|
COLUMN_INDEX_TO_LETTER = Hash.new {|hash,key| hash[key] = hash[key - 1].next }.merge({0 => "A"})
|
|
|
|
belongs_to :user
|
|
has_many :submissions, dependent: :destroy
|
|
after_create :create_spreadsheet
|
|
|
|
has_secure_token
|
|
|
|
validates_presence_of :title
|
|
|
|
def deactivate!(reason = nil)
|
|
self.user.deactivate!(reason)
|
|
end
|
|
|
|
def active?
|
|
self.user.active?
|
|
end
|
|
|
|
def google_spreadsheet_url
|
|
"https://docs.google.com/spreadsheets/d/#{google_spreadsheet_id}/edit" if google_spreadsheet_id.present?
|
|
end
|
|
|
|
def create_spreadsheet
|
|
sheets = Google::Apis::SheetsV4::SheetsService.new
|
|
sheets.authorization = user.google_authorization
|
|
create_object = Google::Apis::SheetsV4::Spreadsheet.new(properties: { title: title})
|
|
spreadsheet = sheets.create_spreadsheet(create_object)
|
|
update(google_spreadsheet_id: spreadsheet.spreadsheet_id)
|
|
end
|
|
|
|
def spreadsheet_service
|
|
@spreadsheet_service ||= Google::Apis::SheetsV4::SheetsService.new.tap do |s|
|
|
s.authorization = user.google_authorization
|
|
end
|
|
end
|
|
|
|
def header_values
|
|
@header_values ||= begin
|
|
values = spreadsheet_service.get_spreadsheet_values(google_spreadsheet_id, 'A1:An').values
|
|
# if there are no headers yet, return an empty array
|
|
if values
|
|
values[0].map(&:strip)
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
end
|
|
|
|
def append(data)
|
|
data = data.with_indifferent_access
|
|
check_spreadsheed_headers!(data)
|
|
|
|
values = header_values.map { |key| data[key] }
|
|
range = "A1:A#{COLUMN_INDEX_TO_LETTER[values.length]}1"
|
|
value_range = Google::Apis::SheetsV4::ValueRange.new(values: [values], major_dimension: 'ROWS')
|
|
|
|
spreadsheet_service.append_spreadsheet_value(google_spreadsheet_id, range, value_range, value_input_option: 'USER_ENTERED')
|
|
end
|
|
|
|
def check_spreadsheed_headers!(data)
|
|
missing_headers = data.keys.map { |k| k.to_s.strip } - header_values
|
|
append_missing_headers(missing_headers) unless missing_headers.empty?
|
|
end
|
|
|
|
def append_missing_headers(missing_headers)
|
|
start_column = COLUMN_INDEX_TO_LETTER[header_values.length]
|
|
end_column = COLUMN_INDEX_TO_LETTER[header_values.length + missing_headers.length]
|
|
range = "#{start_column}1:#{end_column}1"
|
|
value_range = Google::Apis::SheetsV4::ValueRange.new(values: [missing_headers], major_dimension: 'ROWS')
|
|
spreadsheet_service.update_spreadsheet_value(google_spreadsheet_id, range, value_range, value_input_option: 'USER_ENTERED')
|
|
@header_values = nil # reset header values to refresh memoization on next access
|
|
end
|
|
|
|
def to_param
|
|
token
|
|
end
|
|
|
|
end
|