I try to use Redis to cache on rails, but I get a challenge when trying to cache multi-language. Because my Redis needs to be cached with table_translations
I try with some code, but I don't think this is the best way
I have the instance variable to work with Erb template
def index
@posts = fetch_posts
@translations = fetch_translations
puts @posts
puts @translations
end
and Redis fetch like this
private
def fetch_posts
begin
posts = $redis.get "posts"
if posts.nil?
posts = []
Post.all.order("id ASC").each do |post|
posts << post
end
posts = posts.to_json
$redis.set "posts", posts
end
posts = JSON.load posts
rescue => error
puts error.inspect
posts = Post.all
end
posts
end
def fetch_translations
begin
translations = $redis.get "translations"
if translations.nil?
translations = []
Post.all.order("id ASC").each do |post|
post.translations.order("locale ASC").each do |translation|
translations << translation
end
end
translations = translations.to_json
$redis.set "translations", translations
end
translations = JSON.load translations
rescue => error
puts error.inspect
translations = Post.all
end
translations
end
I do that because I need to get all language version of a post, so I make a Redis key for translate
and my output:
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z"}
{"title":"Xin chao","description":"Day la bai viet dau tien, duoc viet tu rails CMS","body":"xin chao cac ban"}
{"title":"Hello World","description":"This is first post from rails CMS","body":"Hello every body"}
I find the best solution to make my output into a key, like this:
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z","title":"Xin chao","description":"Đay la bai viet đau tien, đuoc viet tu rails CMS","body":"xin chao cac ban"}
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z",title":"Hello World","description":"This is first post from rails CMS","body":"Hello every body"}
My code can work correctly, but I need your help to make it better, please help me to improve my skills
Thank for your help
You can use the built in Rails cache handler, this way you won't need to handle .nil?
calls to cache keys.
private
def fetch_posts
posts = Rails.cache.fetch("posts") do
begin
Post.all.order("id ASC").as_json
rescue => error
puts error.inspect
Post.all
end
end
posts
end
def fetch_translations
translations = Rails.cache.fetch("translations") do
begin
Post.all.order("id ASC").map do |post|
post.translations.order("locale ASC").as_json
end.flatten
rescue => error
puts error.inspect
Post.all
end
end
translations
end
I found the solution by follow this stuff How do you add an array to another array in Ruby and not end up with a multi-dimensional result?
concept is flatten all attr in two array and then Hash again this into new array
def fetch_posts
posts = []
Post.all.order("id ASC").each do |post|
post.translations.each do |translation|
posts << [*post.attributes.slice('slug','thumb_url'),*JSON.parse(translation.to_json)].to_h
end
end
end
Hope this help to anyone have question same to me :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.