Hello,
Lets say that I have a model class like `Car < ActiveRecord::Base` and then, I want to extend it with an abstract class in between a sort of `Car < CacheableActiveRecord::Base < ActiveRecord::Base`
In `CacheableActiveRecord::Base` I'll overwrite methods like `find_by`, `find_by!` and `find` with the intention of checking out Redis/Memcached before calling super and letting Rails resolve this to the underlying db, I'm using Rails 4.2.7.1
By extending `Car` an `after_commit` hook will be created for each instance of the `Car` class, that hook will clear the cached key for this model upon commit, This is to get the effect, of releasing the cache on save.
This is an implementation for my `find` method in `CacheableActiveRecord::Base`
```
def self.find(*ids)
expects_array = ids.first.kind_of?(Array)
return ids.first if expects_array && ids.first.empty?
ids = ids.flatten.compact.uniq
case ids.size
when 0
super # calling supper will generate an exception at this point
when 1
id = ids.first
result = get_from_cache(id)
unless result
result = super # I expect this to get the data from db
if result
result = set_to_cache(id, result)
end
end
expects_array ? [ result ] : result
else
super # for now let's just skip on multiple ids
end
rescue RangeError
raise RecordNotFound, "Couldn't find #{@
klass.name} with an out of range ID"
end
```
I have tests for this, and they even seem to work. for the implementation of `set_to_cache` and `get_from_cache` I have the following code
```
def self.get_from_cache(entity_id)
return nil unless entity_id
cached = Rc.get!(get_cache_key(entity_id))
if cached
puts "cache hit"
end
return cached ? Marshal.load(cached) : nil
end
def self.set_to_cache(entity_id, entity)
return nil unless entity && entity_id
dump = Marshal.dump(entity)
Rc.set!(get_cache_key(entity_id), dump)
return Marshal.load(dump)
end
```
My doubts here are:
- Is `Marshal` safe? can one do this? taking into account that this cache will be shared among instances of the same rails app, running in different servers.
- Is it better to serialize to json? is it possible to serialize to json and then rebuilt an object that will work as regular active record object? I mean one on which you can call `.where` queries on related objects and so on?
I'm a newbie to Rails and Ruby, started coding with both two weeks ago, my background is mostly java xD (finding Ruby great BY THE WAY hahaha)
Thank you
Daniel