Rails 全局变量 - 根据 API 的每个请求进行更新

问题描述 投票:0回答:3

我使用 GRAPE gem 来创建 API 端点。

对于简单的用例,让我们考虑一下,当我的 Web 服务被访问时,我访问另一个第三方 REST API,我获取一些值并将这些值分配给一个或两个变量。例如变量1,变量2

这些值经常从第三方 API 更改,因此我也必须不断更新变量值,在 API 代码中使用它或将其作为参数传递给方法时一切都很好。

但是我有几个控制器应该采用更新的变量/要采用的更新值。

目前我所做的是:

class Api < Grape::API     
 version 'v1'
 format :json
 helpers MyProject::Config

resources :foo do      
  get do
    variable1 = #hit third party URL
    $global_variable1 = variable1
  end
 end
end

在控制器中:

 class SampleController < ApplicationController
   def method()
     some_calc = $global_variable1 + other_variable
   end
 end

现在效果很好,除了全局变量之外还有什么更好的使用方法吗? 或者我们可以这样做:

Rails.application.config.variable1 = variable1

哪一个是更好的前进方向?

我尝试在 API 类中像这样设置 @instance 变量,但是在控制器方法中访问它时会给出空字符串。

@variable1 = ""
def self.variable1
  @variable1
end

并像 ClassName.variable1 一样访问它

任何人都可以提出更好的前进方向吗?

ruby-on-rails ruby global-variables ruby-grape
3个回答
1
投票

恕我直言,全局变量是一个坏主意。这或多或少与单例相同。 您将如何更新变量以及谁将执行此操作?什么时候?如何检查是否过期?如果您有多个 ruby 进程并且它们使用不同的值怎么办?

这听起来像是缓存和从缓存读取的服务的一个很好的用例。

class ParameterService
  def get(parameter_name)
    if parameter is not in cache or expired
      read from external service and store in cache
    end
    return value from cache
  end
end

缓存可以是 Redis、DB、Memcached 之类的东西。


1
投票
理想情况下,您可以在启动期间创建一个对象来保存这些参数,然后通过某种形式的依赖项注入将该单个实例注入到需要它们的每个类中,但由于我不知道有任何常用的 Rails 依赖项注入方案,我建议这两种选择。

有些人不喜欢单例,但你可以将它们存储在单例类中。

require 'singleton' class APIParams include Singleton attr_accessor :v1, :v2 end APIParams.instance.v1 = 3 puts APIParams.instance.v1

这可能有点矫枉过正,但您也可以为它们创建一个模型并将它们存储在数据库中。 如果您有多个资源需要存储同一组变量(例如

api_key

 和/或标记),这可能会很有用。

class APIResource < ActiveRecord::Base # you probably would want some `belongs_to`, has_a relationships here to associate these with the models used in your controllers. end

由包含如下字段的表格支持

create_table "api_resources", force: :cascade do |t| t.string "name", t.string "api_key", t.string "token" end
    

0
投票
检查当前属性,应该会有帮助

https://api.rubyonrails.org/v8.0.0/classes/ActiveSupport/CurrentAttributes.html

© www.soinside.com 2019 - 2024. All rights reserved.