Last active
December 15, 2015 12:19
-
-
Save evie404/5259478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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