I am trying to cache server API response using Rail.cache.fetch feature but it seems like just always 'nil' instead cached data. Method below runs one time, then always fails with 'access to nil class' kind error when I am trying to go through @my_api_data_ variable
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
I hope maybe someone knows why it goes bad each time
I tried to add line "@my_api_data_" right before the end of cache block. This is the same error I got on original circumstances:
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|
It seems that the problem here is that you have to return @my_api_data_
at the end of the block. Let check the code below:
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
Note that the first time that you call the api_statuses_
method all the blocked will be executed, and the return value will be written to the cache under the api_repsonse_m_
key. So, the next time that you call api_statuses_
, and if the time in expires_in
has not expired, it will return the value save in the cache and the block will not be executed.
Also, could you show us where and how are you using this method? Showing the code and the error log could be great to understand the problem.
Updated: It seems that you are not using correctly this. You should call the api_statuses_
method in the index method under the MydataController
controller, and save the return value to a variable that will be use in your view.
For instance:
module Private
class MydataController
def index
@api_statuses = api_statuses_
end
end
end
Then, in your view:
.row
.market-top-coin-boxes
- @api_statuses.each do |pair_data|