rails: how to get all key-values from Rails.cache - ruby-on-rails

I want to maintain an user online/offline list with Rails.cache(memory_store).
Basically if a request /user/heartbeat?name=John reached Rails server, it will simply:
def update_status
name = params.require(:name)
Rails.cache.write(name, Time.now.utc.iso8601, expires_in: 6.seconds)
end
But how could I get all the data stored in Rails.cache similarly as following?
def get_status
# wrong codes, as Rails.cache.read doesn't have :all option.
ary = Rails.cache.read(:all)
# deal with array ...
end
I googled for a while, it seems Rails.cache doesn't provide the method to get all the data directly. Or there is better way to store the data?
I'm using Rails 5.0.2.
Thanks for your time!

If you have redis you can use sth like Rails.cache.redis.keys

You can get all keys with code:
keys = Rails.cache.instance_variable_get(:#data).keys

In addition, you can iterate on the keys to get their values and display them all
keys = Rails.cache.instance_variable_get(:#data).keys
keys.each{|key| puts "key: #{key}, value: #{Rails.cache.fetch(key)}"}
or map them all directly as such:
key_values = Rails.cache.instance_variable_get(:#data).keys.map{|key| {key: key, value: Rails.cache.fetch(key)}}
In addition I would check beforehand the amount of keys to make sure I would not come up with a gigantic object (and if so, restrict the key_value array generated to the first 1000 items for instance).
You could use:
Rails.cache.instance_variable_get(:#data).keys.count
or just look at the last line of the stats command:
Rails.cache.stats

None of the answers seem to work if you're using Redis. Instead, you will have to use redis-rb:
redis = Redis.new(url: ENV["REDIS_URL"])
redis.keys("*")

The above answeres helped me. The existing cache values can been seen by looping
Rails.cache.redis.keys.each{ |k| puts k if Rails.cache.exist?(k)}

If you have connection pooling, try:
Rails.cache.redis.with do |conn|
conn.keys
end

Related

Storing/Retrieving values in a Rails cookie and in different controller [duplicate]

I am trying to store an array on rails an getting error on the decoding.
I use cookies[:test] = Array.new
And when I am trying to decode
#test = ActiveSupport::JSON.decode(cookies[:test])
I am getting an error.
Whats the proper way to achieve what I am trying to ?
When writing to the cookie I usually convert the array to a string.
def save_options(options)
cookies[:options] = (options.class == Array) ? options.join(',') : ''
end
Then I convert back into an array when reading the cookie.
def options_array
cookies[:options] ? cookies[:options].split(",") : []
end
I'm not sure if this is "the right way" but it works well for me.
The "Rails way" is to use JSON.generate(array), since it's what is used in the second example in the Cookies docs:
# Cookie values are String based. Other data types need to be serialized.
cookies[:lat_lon] = JSON.generate([47.68, -122.37])
Source: http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
When you want to read it back, just use JSON.parse cookies[:lat_lon] for example, and it'll provide you an array.
Use session, not cookies. You don't have to decode it, rails handles that for you. Create the session the same way you already are:
session[:test] = Array.new
and when you need it, access it like normal
session[:test]
# => []

How to store array on a cookie rails 4?

I am trying to store an array on rails an getting error on the decoding.
I use cookies[:test] = Array.new
And when I am trying to decode
#test = ActiveSupport::JSON.decode(cookies[:test])
I am getting an error.
Whats the proper way to achieve what I am trying to ?
When writing to the cookie I usually convert the array to a string.
def save_options(options)
cookies[:options] = (options.class == Array) ? options.join(',') : ''
end
Then I convert back into an array when reading the cookie.
def options_array
cookies[:options] ? cookies[:options].split(",") : []
end
I'm not sure if this is "the right way" but it works well for me.
The "Rails way" is to use JSON.generate(array), since it's what is used in the second example in the Cookies docs:
# Cookie values are String based. Other data types need to be serialized.
cookies[:lat_lon] = JSON.generate([47.68, -122.37])
Source: http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
When you want to read it back, just use JSON.parse cookies[:lat_lon] for example, and it'll provide you an array.
Use session, not cookies. You don't have to decode it, rails handles that for you. Create the session the same way you already are:
session[:test] = Array.new
and when you need it, access it like normal
session[:test]
# => []

What is the redis equivalent of storing an array?

I'd like to use Redis and not my session for this for obvious reasons.
Old country code :
session[:some_stuff] = #my_objects.map(&:id)
Then later :
session[:some_stuff].each{|obj| ..
Alternatively,
I would like to store this map of id's into redis. And then retrieve them. I can't find any thing relevant on other web resources. Any ideas?
You haven't written about how you have your Redis connection/adapter set up but it's basically SADD for adding elements to a Redis set and SMEMBERS to retrieve all the elements.
http://redis.io/commands#set
I tried to use the redis-store gem thinking that would solve a few problems but it turns out it doesn't work. Even the supposibly stable 1.0.0 version.
So this is what I did and it worked out extraordinarily well :
def first_method
$redis = Redis.new
#customers.map(&:id).each{|c|$redis.sadd('export', c)}
def other_method
#customers = []
$redis.smembers('export').each{|c|#customers << Customer.find(c)}
Notes:
You only need to identify what $redis is once in one method. Then it saves itself into a stateless place outside of your MVC architecture.

Random jokes in a skit (activerecord)

I am working on populating my database with test data using populate.rake:
Repertoire.includes(:jokes).each do |r|
#jokes = r.jokes
Skit.populate 8..12 do |skit|
skit.joke_id = #jokes[rand(#jokes.count)].id
end
end
This is giving me a RuntimeError: Called id for nil.
How can I populate a skit with random jokes?
sort_by {rand} should sort your array of jokes.
Or, there is also doing an .order("rand()/random()") (depending on your db) in your Repertoire query and putting a limit on the query.
Not sure if this will fix your problem but Ruby has a rand method for arrays so you should be able to call #jokes.rand.id instead. Seems like that would simplify things and maybe even fix your error.

How to store different site parameters in database with Rails?

There are a lot of ways to store site preferences in database. But what if I need to manage datatypes. So some preferences will be boolean, others strings, others integers.
How can I organize such store?
I wrote a gem that does exactly this, and recently updated it for Rails 3:
For Rails 3:
http://github.com/paulca/configurable_engine
For Rails 2.3.x
http://github.com/paulca/behavior
Enjoy!
I am quite lazy with preferences and store the data as serialized JSON or YAML Hashes. Works really well, and generally preserves the data types as well.
I used a single table with a single row, and each column representing one preference. This makes it possible to have different datatypes.
To be able to retrieve a preference, I overrode method_missing to be able to retrieve the preference value directly from the class name without requiring an instance, something like this:
class Setting < ActiveRecord::Base
##instance = self.first
def self.instance
##instance
end
def self.method_missing(method, *args)
option = method.to_s
if option.include? '='
var_name = option.gsub('=', '')
value = args.first
##instance[var_name] = value
else
##instance[option]
end
end
end
Thus, to retrive a setting, you would use:
a_setting = Setting.column_name
Rails Migrations are used to create and update the database.
http://guides.rubyonrails.org/migrations.html

Resources