Мне не особенно нравится название Wrapper
для этого класса, но, эй, дело не в этом.
На вашем месте я бы поместил папку wrappers
в app
, а затем поместил google_cal_wrapper.rb
в эту папку. Таким образом, вы в конечном итоге:
app
|- assets
|- controllers
|- ...
|- wrappers
|- google_cal_wrapper.rb
Таким образом, он должен быть автоматически загружен и доступен в вашем контроллере просто как GoogleCalWrapper
.
Кстати, в моих проектах, где я использую google-api-client
(и другие клиенты API), я называю такие вещи services
, и моя структура каталогов выглядит примерно так (естественно, заменяя app_name
и AppName
на фактическое имя, которое я использую для моего текущего приложения):
app
|- assets
|- controllers
|- ...
|- services
| |- app_name
| | |- service_base.rb
| |- google
| | |- calendar
| | | |- list_service.rb
| | |- calendar_service.rb
| | |- client_service.rb
| | |- service_base.rb
| |- quickbooks
| | |- consumer_service.rb
| | |- service_base.rb
| |- ...
|- ...
А мои занятия выглядят примерно так:
class AppName::ServiceBase
attr_accessor *%w(
args
).freeze
# allows you to call Google::Service.call(current_user: current_user)
# without having to do Google::Service.new(current_user: current_user)
# which I prefer.
class << self
def call(args={})
new(args).call
end
end # Class Methods
#==================================================================================
# Instance Methods
#==================================================================================
def initialize(args={})
@args = args
assign_args
end
private
# creates an attr_accessor for each k,v pair in args. So,
# for instance, when called like
# Google::Service.call(current_user: current_user),
# the new service instance will have a method called
# 'current_user' that returns the current_user
def assign_args
args.each do |k,v|
class_eval do
attr_accessor k
end
send("#{k}=",v)
end
end
end
Базовый класс для классов Google:
class Google::ServiceBase < AppName::ServiceBase
private
def client
@client ||= Google::ClientService.call(current_user: current_user)
end
def calendar_service
@calendar_service ||= Google::CalendarService.call(current_user: current_user)
end
end
Класс, который настраивает calendar_service
class Google::CalendarService < Google::ServiceBase
#==================================================================================
# Instance Methods
#==================================================================================
def call
client.discovered_api('calendar', 'v3')
end
end
Класс, который настраивает клиент Google
class Google::ClientService < Google::ServiceBase
delegate *%w(
token
refresh_token
), to: :current_user
#==================================================================================
# Instance Methods
#==================================================================================
def call
[
:token,
:refresh_token,
:client_id
:client_secret
].each do |client_attribute|
client.authorization.send("#{client_attribute}=", send(client_attribute))
end
client.authorization.refresh!
client
end
private
def client
@client ||= Google::APIClient.new
end
def client_id
ENV['GOOGLE_CLIENT_ID']
end
def client_secret
ENV['GOOGLE_CLIENT_SECRET']
end
end
Класс для захвата calendars_list
class Google::Calendar::ListService < Google::ServiceBase
#==================================================================================
# Instance Methods
#==================================================================================
def call
# do some stuff like you have commented out in your controller
# like (naturally, insert code that actually works):
calendar_service.calendar_list.list
end
end
Так что вы можете сделать что-то в вашем controller
, например:
def index
if user_signed_in?
@event = current_user.posts.build
@calendar_list = Google::Calendar::ListService.call(current_user: current_user)
else
@event = Event.new
end
end
И теперь вашему контроллеру не нужно ничего знать о JSON.parse
или response
или .execute
или о чем-либо кроме Google::Calendar::ListService.call(current_user: current_user)
.