繁体   English   中英

Rails:如何将 gem 的类保存为我的数据库中的模型?

[英]Rails: how to save a gem's class as a model in my database?

我一直在构建一个 Google Tasks 集成应用程序,刚刚切换到使用 Google API 客户端( gem 'google-api-client', '~> 0.34'

这给了我一些我真正开始喜欢的课程:

Google::Apis::TasksV1::Task
Google::Apis::TasksV1::TaskList
Google::Apis::TasksV1::Tasks # (for multiple records)
Google::Apis::TasksV1::TaskLists # (for multiple records)

这些类带有我想要的所有属性,我认为在我的数据库中实际拥有这些记录会很好,而不是我现在正在做的事情,即 OAuth 的 HTTP 请求(使用 gem 提供的方法)

将他们的 gem 集成到自定义类中,我可以执行以下操作:

> ts = TaskService.new(user)
=> #<TasksService:0x00007f973be03bc8 @user=#<User #userstuff>, @service=#<Google::Apis::TasksV1::TasksService:0x00007f973be03b28 @root_url="https://www.googleapis.com/", @base_path="tasks/v1/", @upload_path="upload/tasks/v1/", @batch_path="batch/tasks/v1", @client_options=#<struct Google::Apis::ClientOptions #morestuff>, @request_options=#<struct Google::Apis::RequestOptions authorization=#<Signet::OAuth2::Client:0x00007f973be02020 @authorization_uri=#<Addressable::URI:0x3fcb9df05304 URI:https://accounts.google.com/o/oauth2/auth>, @token_credential_uri=#<Addressable::URI:0x3fcb9db99f08 URI:https://accounts.google.com/o/oauth2/token>, @client_id="secret", @client_secret="secret", @code=nil, @expires_at=nil, @issued_at=nil, @issuer=nil, @password=nil, @principal=nil, @redirect_uri=nil, @scope=nil, @state=nil, @username=nil, @access_type=:offline, @expiry=60, @extension_parameters={}, @additional_parameters={}, @access_token="secret", @id_token=nil>, retries=0, header=nil, normalize_unicode=false, skip_serialization=false, skip_deserialization=false, api_format_version=nil, use_opencensus=true>>>

> ts.service.list_tasklists
Sending HTTP get https://www.googleapis.com/tasks/v1/users/@me/lists?
200
#<HTTP::Message:0x00007f973b79ceb0 #all the stuff>
Success - #<Google::Apis::TasksV1::TaskLists:0x00007f973e032168
 @etag="\"LTY2NzExNzU1Mg\"",
 @items=
  [#<Google::Apis::TasksV1::TaskList:0x00007f973e0a2a58
    @etag="\"Mzk0NzU3MDky\"",
    @id="MDc1MjQ5ODU0NzUwMjI4NDkwMTM6MDow",
    @kind="tasks#taskList",
    @self_link=
     "https://www.googleapis.com/tasks/v1/users/@me/lists/MDc1MjQ5ODU0NzUwMjI4NDkwMTM6MDow",
    @title="My list",
    @updated=Wed, 18 Dec 2019 05:42:34 +0000>,
   #<Google::Apis::TasksV1::TaskList:0x00007f973bf298b8
    @etag="\"Mzk0OTEzMTI0\"",
    @id="eHFkTG9UUkl3d1ZQcTdCOA",
    @kind="tasks#taskList",
    @self_link=
     "https://www.googleapis.com/tasks/v1/users/@me/lists/eHFkTG9UUkl3d1ZQcTdCOA",
    @title="Another List",
    @updated=Wed, 18 Dec 2019 05:45:10 +0000>,
   ... # brevity is the soul of ...

=> #<Google::Apis::TasksV1::TaskLists:0x00007f973e032168 @etag="\"LTY2NzExNzU1Mg\"", @items=[#<Google::Apis::TasksV1::TaskList:0x00007f973e0a2a58 @etag="\"Mzk0NzU3MDky\"", @id="MDc1MjQ5ODU0NzUwMjI4NDkwMTM6MDow", @kind="tasks#taskList", @self_link="https://www.googleapis.com/tasks/v1/users/@me/lists/MDc1MjQ5ODU0NzUwMjI4NDkwMTM6MDow", @title="FamilyPromiseGR's list", @updated=Wed, 18 Dec 2019 05:42:34 +0000>, #<Google::Apis::TasksV1::TaskList:0x00007f973bf298b8 @etag="\"Mzk0OTEzMTI0\"", @id="eHFkTG9UUkl3d1ZQcTdCOA", @kind="tasks#taskList", @self_link="https://www.googleapis.com/tasks/v1/users/@me/lists/eHFkTG9UUkl3d1ZQcTdCOA", @title="Vinewood Ave NE", @updated=Wed, 18 Dec 2019 05:45:10 +0000>, ... # brevity is the soul of ...

这些项目作为结构化类回来了! 这很棒!

但是,每次调用都有大量的延迟。

我正在作业中运行这些命令,但我也在考虑将这些命令保存到我的数据库 (postgresql) 中,并且只是比较updated时间戳,而不是每次需要时都提取信息。

所以,这是我的问题:

我怎样才能按原样使用该类并使其成为我数据库中的模型?

我希望能够调用Google::Apis::TasksV1::Task.create(tasklist_attrs)和其他此类模型类型方法。

我注意到它们的响应不像我自己的类(从ActiveRecord::Base继承):

2.6.3 :008 > User.new
 => #<User id: nil, name: nil, title: nil, phone: nil, admin: false, staff: false, client: false, volunteer: false, contractor: false, email: "", oauth_provider: nil, oauth_id: nil, oauth_image_link: nil, oauth_token: nil, oauth_refresh_token: nil, oauth_expires_at: nil, created_at: nil, updated_at: nil, discarded_at: nil>

2.6.3 :009 > Google::Apis::TasksV1::Task.new
 => #<Google::Apis::TasksV1::Task:0x00007f973e2d8908> # no nil attributes by default?

在我看来,您需要的是缓存:

伪代码,请根据您的情况进行调整,但这样的事情会做:

ts = TaskService.new(user)
tasklist = Rails.cache.fetch("list-tasklists-#{user.id}", expires_in: 2.hours) do
  ts.service.list_tasklists
end

然后,您可以编写一个连接到 API 的缓存失效器,可能还有一个缓存热重载器,这样您的用户的缓存总是在那里。

编辑:
我知道这不是你所要求的,但它可能是一个解决方案,看看你的用例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM