I am trying to implement redis cache on a rails application. Till now I am able to cache the active record data using redis cache. I am able to fetch all the records at once using get method. But I am having difficult time figuring out how to fetch a single record using id since the the data produced by redis is in string data type.
Following is the data cached by redis:
"set" "bookstore:authors" "[{\"id\":1,\"name\":\"Stephenie Meyer\",\"created_at\":\"2018-05-03T10:58:20.326Z\",\"updated_at\":\"2018-05-03T10:58:20.326Z\"},{\"id\":2,\"name\":\"V.C. Andrews\",\"created_at\":\"2018-05-03T10:58:20.569Z\",\"updated_at\":\"2018-05-03T10:58:20.569Z\"}]
Now I am calling
authors = $redis.get('authors')
to display all the authors.
How can I fetch a single author using his id?
Helper method to fetch authors
def fetch_authors
authors = $redis.get('authors')
if authors.nil?
authors = Author.all.to_json
$redis.set("authors", authors).to_json
$redis.expire("authors", 5.hour.to_i)
end
JSON.load authors
end
For your use case, using a hash is probably better. You could use the following commands to achieve that:
HSET bookstore:authors 1 "<author json>"
HGET bookstore:authors 1 // Returns that author's json data
Or you can store each author on its own:
SET bookstore:authors:1 <author_json>
GET bookstore:authors:1 // Returns that author's json data
Related
I have a rails(5.1) application with postgres(9.6) as a DB. In one of tables I have jsonb field, and all that I need is just to retrieve this string and send it to client. Why do i need it? Converting to json takes half of total request time
my_record.my_json_field # returns hash
my_record.read_attribute(:my_json_field) # also returns hash
# even this hack returns hash
MyRecord.select('my_json_field as temp_field').first[:temp_field]
I found two solutions:
# proposed by Sergio Tulentsev
# It's a fastest way. you will receive just a hash with fields that you selected
MyRecord.connection.execute(MyRecord.my_scope.to_sql)
# Another option is to select that data as a text.
# In that case you will receive ActiveRecord objects
MyRecord.select('*', 'my_json_field::text as my_field_as_text').first.my_field_as_text
(porting suggestion from comments, which worked)
Try MyRecord.connection.execute_sql (or what is it called). In all of the examples above you go through the model, which respects your schema and deserializes the hash. You need the raw db connection.
I'm currently working on saving a user social media posts in my app. The basic idea is to check if the post exists if it does update the data or if not create a new row. Right now I'm looping through all of the post that I receive from the social platform so potentially I'm looping through 3,000 and adding them to the database.
Is there a way that I could rewrite this to save all the items at once, which hopefully would speed up the save method?
post_data.each do |post_data_details|
post_instance = Post::Tumblr.
where(platform_id: platform_id).
where("data ->> 'id' = ?", post_data_details["id"].to_s).
first_or_initialize
exisiting_data = post_instance.data
new_data = exisiting_data.merge! post_data_details.to_hash
post_instance.data = new_data
post_instance.refreshed_at = date
post_instance.save!
end
It is good practice to run such long-running jobs via sidekiq or other background jobs solution.
You can also use single ActiveRecord transaction.
http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
But keep in mind, that if one of records will be invalid - whole trasaction will be rollbacked.
I use Soulmate to autocomplete search results, however I want to be able to delete records after a while so they don't show up in the searchfield again. To reload the list with Soulmate seems a bit hacky and unnecessary.
I have used json to load and I have a unique record "id"
{"id":1547,"term":"Foo Baar, Baaz","score":85}
How can I delete that record from redis so it wont show up in the search results again?
It is not trivial to do it directly from Redis, using redis-cli commands.
Looking at soulmate code, the data structure is as follows:
a soulmate-index:[type] set containing all the prefixes
a soulmate-data:[type] hash object containing the association between the id and the json object.
per prefix, a soulmate-index:[type]:[prefix] sorted set (with score and id)
So to delete an item, you need to:
Retrieve the json object from its id (you already did it) -> id 1547
HDEL soulmate-data:[type] 1547
Generate all the possible prefixes from "Foo Baar, Baaz"
For each prefix:
SREM soulmate-data:[type] [prefix]
ZREM soulmate-index:[type]:[prefix] 1547
Probably it would be easier to directly call the remove method provided in the Soulmate.Loader class from a Ruby script, which automates everything for you.
https://github.com/seatgeek/soulmate/blob/master/lib/soulmate/loader.rb
I have some Wordpress blogs that have RSS feeds.
I want to know if 1 RSS is updated. So that I can run a resque job.That fetches the feeds.
Are there any rubygem that can determinate if a RSS feed is updated?
Like an RSS feed notification gem.
A different approach:
Parse feed to internal memory using https://www.ruby-toolbox.com/categories/feed_parsing and check for the latest message with a cron job (periodically for example every 5 hours) and fetch it accordingly
Take a look at Feedzirra. It is able to do what you need:
# updating a single feed
updated_feed = Feedzirra::Feed.update(feed)
# an updated feed has the following extra accessors
updated_feed.updated? # returns true if any of the feed attributes have been modified. will return false if only new entries
updated_feed.new_entries # a collection of the entry objects that are newer than the latest in the feed before update
# updating multiple feeds. it expects a collection of feed objects
updated_feeds = Feedzirra::Feed.update(feeds.values)
Check Feedzirra's readme for other methods available.
I am using central_logger(0.3.3) gem for my rails app.
I follow each instruction as per documentation https://github.com/customink/central_logger.
record inserted successfully. But I want to fetch records of central_logger to show analysis
in my app is there any way?
please help
I was able to access the db and its records as per the documentation
db = Rails.logger.mongo_connection #specifies db, NO Need to change anything use as is
collection = db[Rails.logger.mongo_collection_name] #specifies mongo collection, NO Need to change anything use as is.
cursor = collection.find(:action => 'show') #get all central_logger records with action show
cursor.each do |obj|
obj ## A single mongo record object
end
Works for me...!