Reputation: 2074
I am using redis cache to fetch data in my rails applications. In simple words I can say that I have two application first is based on rails 4 and second is on rails 6. I have to use cache data in both application.
In rails 4 application :- I have created cache in rails 4 application and It fetched data successfully.
Rails.cache.fetch("test_cache"){User.last}
=> #<User id: 100973, email: "xxxx.com", encrypted_password: "$2a$10$D8aOhoSWvNWeEQE2swAX2OEVIF5H0aY8sR/fGVQ3BhU...........>
In rails 6 application :- But When I want to load same cache in my rails 6 application gives me an error.
Rails.cache.fetch("test_cache"){User.last}
Traceback (most recent call last):
2: from (irb):18
1: from (irb):18:in `rescue in irb_binding'
NameError (uninitialized constant ActiveRecord::AttributeSet)
Did you mean? ActiveRecord::Attributes
Then I came to one solution, save data with as_json
Rails.cache.fetch("test_cache"){User.last.as_json}
which successfully work and fetched data on both application but then I have one more problem how can I access model methods, associations etc etc...
for the same.
Any suggestion or any idea ?
Upvotes: 2
Views: 692
Reputation: 18454
For non-string values in cache Rails uses Marshal.dump
(and also compresses it via deflate for large ones). Marshalled data can be thought as something in between data and code, because it has references to class names and internal structure. That's why it has limitations: it can be unmarshalled only with same ruby version (see ruby docs on that) and app should have same classes.
Obviously, ActiveRecord::Base
structure is different in rails 4 and rails 6 thus incompatible when marshalled.
To have compatibility your only option is to cache only basic ruby types and POROs, that do not reference any classes that are different in your apps. Your attempt with as_json
does exactly that - store a Hash representation of the model.
But actually first move is to think again about what exactly and why you want to cache, there several thoughts to consider:
User.find(primary_key_value_here)
) are almost as fast.hash = Rails.cache.fetch("last_registered_user"){
User.last.yield_self{|u|
{
user_id: u.id,
name: u.name,
registered_at: u.created_at,
invited_by: u.invited_by.name
}
}
}
Upvotes: 1