Skip to content

Instantly share code, notes, and snippets.

@evie404
Last active December 15, 2015 12:19
Show Gist options
  • Save evie404/5259478 to your computer and use it in GitHub Desktop.
Save evie404/5259478 to your computer and use it in GitHub Desktop.
# I use nateware/redis-objects as an easy way to implement atomic counters in my ActiveRecord models in Rails.
# But I still need counters in sql to sort models with them.
# So the CounterSyncWorker goes through the object space, selects all class that is an AR model and includes Redis::Objects,
# check for all columns that have _sql equivalents, fetches the value in redis and store into the AR attribute.
# Example:
# when uploading a photo that belongs to first user:
# user = User.first
# photo = user.photos.create
# user.photo_count # 1
# user.photo_count_sql # 0
# After scheduled counter_sync,
# user = User.first
# user.photo_count # 1
# user.photo_count_sql # 1
class CounterSyncWorker
include Sidekiq::Worker
sidekiq_options queue: "counter_sync"
def perform()
#http://stackoverflow.com/questions/2393697
#select models with counters
models = ObjectSpace.each_object(Class).select
{ |klass| klass < ActiveRecord::Base && klass.included_modules.include?(Redis::Objects) }
models.each do |model|
columns = model.columns_hash.keys
sql_counts = model.columns_hash.keys.select { |s| s.include?('_sql') }
if sql_counts.count > 0
model.all.each do |instance|
sql_counts.each do |sql_count|
instance.send("#{sql_count}=", instance.send(sql_count[0..-5]).to_i)
end
instance.save
end
end
end
self.class.perform_in(30.minutes)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment