Hello tinyforms
This commit is contained in:
3
app/models/application_record.rb
Normal file
3
app/models/application_record.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
end
|
||||
22
app/models/authentication.rb
Normal file
22
app/models/authentication.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
class Authentication < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
def expired?
|
||||
expires_at <= Time.current
|
||||
end
|
||||
|
||||
def google_authorization
|
||||
@google_authorization ||= CLIENT_SECRETS.to_authorization.tap do |c|
|
||||
c.access_token = self.access_token
|
||||
c.refresh_token = self.refresh_token
|
||||
c.expires_at = self.expires_at
|
||||
if expires_at < 1.minute.from_now
|
||||
c.refresh!
|
||||
self.access_token = c.access_token if c.access_token.present?
|
||||
self.refresh_token = c.refresh_token if c.refresh_token.present?
|
||||
self.expires_at = Time.at(c.expires_at) if c.expires_at.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
0
app/models/concerns/.keep
Normal file
0
app/models/concerns/.keep
Normal file
69
app/models/form.rb
Normal file
69
app/models/form.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
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 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
|
||||
18
app/models/submission.rb
Normal file
18
app/models/submission.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class Submission < ApplicationRecord
|
||||
belongs_to :form
|
||||
after_create :append_to_spreadsheet
|
||||
validates_presence_of :data
|
||||
|
||||
def data=(value)
|
||||
sanitized_data = {}
|
||||
value.each do |key, value|
|
||||
sanitized_data[key] = value.to_s
|
||||
end
|
||||
write_attribute(:data, sanitized_data)
|
||||
end
|
||||
|
||||
def append_to_spreadsheet
|
||||
result = form.append(data)
|
||||
update_column(:appended_at, Time.current) if result.updates.updated_rows > 0
|
||||
end
|
||||
end
|
||||
26
app/models/user.rb
Normal file
26
app/models/user.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class User < ApplicationRecord
|
||||
has_many :authentications, dependent: :destroy
|
||||
has_many :forms, dependent: :destroy
|
||||
|
||||
def self.find_by_oauth_info(auth_client)
|
||||
oauth = Google::Apis::Oauth2V2::Oauth2Service.new
|
||||
oauth.authorization = auth_client
|
||||
user_info = oauth.get_userinfo
|
||||
|
||||
if user = User.find_by(google_id: user_info.id)
|
||||
return user, user.authentications.last
|
||||
else
|
||||
user = User.create(name: user_info.name, email: user_info.email, google_id: user_info.id)
|
||||
authentication = user.authentications.create(
|
||||
access_token: auth_client.access_token,
|
||||
refresh_token: auth_client.refresh_token,
|
||||
expires_at: Time.at(auth_client.expires_at)
|
||||
)
|
||||
return user, authentication
|
||||
end
|
||||
end
|
||||
|
||||
def google_authorization
|
||||
authentications.last.google_authorization
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user