【问题标题】:Rails.cache.fetch does not work for array of jsonRails.cache.fetch 不适用于 json 数组
【发布时间】:2018-06-22 10:27:14
【问题描述】:

我正在尝试使用 Rail.cache.fetch 功能缓存服务器 API 响应,但似乎总是“nil”而不是缓存数据。下面的方法运行一次,然后在我尝试通过 @my_api_data_ 变量时总是失败并出现“访问零类”类错误

def index
  api_statuses_

end
def api_statuses_
  Rails.cache.fetch('api_repsonse_m_', expires_in: 3.minute) do


      @mypairs_ = ['ticker1','ticker2', 'ticker3', 'ticker4', 'ticker5', 'ticker6', 'ticker7', 'ticker8', 'ticker9', 'ticker10']

      @my_api_data_ = []
      @my_api_data_poplr = []
      url = 'https://myserver.com/ticker/'

      @mypairs_.each do |item_|
        uri = URI(url + item_)
        response = Net::HTTP.get(uri)
        begin
          #response is like this {"status":"valu1","time":"valu2","data":"valu3"}
          myresult = JSON.parse(response)
        rescue JSON::ParserError

        end
        #Rails.logger.info myresult
        @my_api_data_.push(myresult);
      end

  end
end

我希望也许有人知道为什么每次都会变坏

我试图在缓存块的末尾添加“@my_api_data_”行。这是我在原始情况下遇到的相同错误:

I, [2018-01-13T19:29:14.384766 #5716]  INFO -- : Processing by Private::MydataController#index as HTML
I, [2018-01-13T19:29:14.403774 #5716]  INFO -- :   Rendered private/mydata/index.html.slim within layouts/mydatalayout_ (0.7ms)
I, [2018-01-13T19:29:14.403919 #5716]  INFO -- : Completed 500 Internal Server Error in 19ms
F, [2018-01-13T19:29:14.405077 #5716] FATAL -- : 
ActionView::Template::Error (undefined method `each' for nil:NilClass):
    37:         .row
    38:           /! Top head coin-boxes
    39:           .market-top-coin-boxes
    40:             - @my_api_data_.each do |pair_data|

【问题讨论】:

  • 你能在 Rails.cache.fetch 块的末尾返回@my_api_data_
  • 我已经添加了。没有与 nil 类相关的错误,但似乎没有缓存。每次我按下刷新按钮时,它都会加载更新的数据。我在控制器的单行中运行“api_statuses_”方法。然后我在 slim_template 中读取了@my_api_data_
  • 不相关的评论但是:为什么你总是在变量和方法名称的末尾添加_?
  • 相关评论:开发中会发生这种情况吗?如果是这样,可能是因为您的缓存存储设置为null_store
  • 我在生产中工作。我认为在 ruby​​ 方法名称中使用 _ 字符没有害处,不是吗?

标签: ruby-on-rails ruby caching jsonapi-resources


【解决方案1】:

看来这里的问题是你必须在块的末尾返回@my_api_data_。让我们检查下面的代码:

def api_statuses_
  Rails.cache.fetch('api_repsonse_m_', expires_in: 3.minute) do
    @mypairs_ = ['ticker1','ticker2', 'ticker3', 'ticker4', 'ticker5', 'ticker6', 'ticker7', 'ticker8', 'ticker9', 'ticker10']

    @my_api_data_ = []
    @my_api_data_poplr = []
    url = 'https://myserver.com/ticker/'

    @mypairs_.each do |item_|
      uri = URI(url + item_)
      response = Net::HTTP.get(uri)
      begin
        #response is like this {"status":"valu1","time":"valu2","data":"valu3"}
        myresult = JSON.parse(response)
      rescue JSON::ParserError
      end
      #Rails.logger.info myresult
      @my_api_data_.push(myresult);
    end
    @my_api_data
  end
end

注意,第一次调用api_statuses_方法时,所有阻塞都会被执行,返回值会写入api_repsonse_m_键下的缓存中。所以,下次调用api_statuses_,如果expires_in的时间还没有过期,就会返回值保存在缓存中,block不会被执行。

另外,您能告诉我们您在哪里以及如何使用这种方法吗?显示代码和错误日志有助于理解问题。

已更新:您似乎没有正确使用它。您应该在MydataController 控制器下的索引方法中调用api_statuses_ 方法,并将返回值保存到将在您的视图中使用的变量中。

例如:

module Private
  class MydataController
    def index 
      @api_statuses = api_statuses_
    end
  end
end

那么,在你看来:

.row
  .market-top-coin-boxes
    - @api_statuses.each do |pair_data|

【讨论】:

  • 我在缓存块的末尾添加了“@my_api_data”,但我得到了同样的错误。但是,当我使用“return @my_api_data”时它不会引发错误,但这种情况根本没有缓存!您可以在我的原始帖子中看到我的错误日志和更新信息
  • 你必须调用方法:api_statuses_.each do |pair_data|
  • @VitaliGrabovski 看来您没有正确使用此方法,您能再检查一下我的评论吗?我已经更新了。
【解决方案2】:

为什么在视图中使用“@my_api_data_”?

使用

def index
  @result = api_statuses_
end

在您的视图文件中使用@result。注意,如果缓存命中,传递给 Rails.cache.fetch 的块不会运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多