artsy / garner

A set of Rack middleware and cache helpers that implement various caching strategies.
MIT License
343 stars 24 forks source link

Does Garner support binding ActiveRecord models? #84

Open mfunaro opened 9 years ago

mfunaro commented 9 years ago

Just getting started with Garner and I am having trouble binding to ActiveRecord models. I debugged down into the code and it seems that if you bind an ActiveRecord model class such as garner.bind(Patient) ... end, by default the SafeCacheKey strategy will be used, but since the model class wont respond to :cache_key or :updated_at, we return from the apply method of the strategy with no binding_keys which effectively skips the cache.

Am I doing something wrong? I tried figure out what to do with ActiveRecord from the Mongoid samples.

Any help would be greatly appreciated, also sorry if this is not the correct place for questions, I looked for a Google Group and didn't find one.

mfunaro commented 9 years ago

After some more spelunking through the code, I see that my use case is not implemented yet. No need to look into this for me. I'm going to see if I can replicate some of the Mongoid features in ActiveRecord.

dblock commented 9 years ago

Would be really happy to see complete ActiveRecord support! Currently we say:

Garner provides rudimentary support for ActiveRecord. To use ActiveRecord models for Garner bindings, use Garner::Mixins::ActiveRecord::Base. You can set it up in an initializer:

require "garner/mixins/active_record"

module ActiveRecord
  class Base
    include Garner::Mixins::ActiveRecord::Base
  end
end
fancyremarker commented 9 years ago

Hey @mfunaro, I'm using Garner w/ ActiveRecord, but can confirm that binding to classes won't work out of the box (just instances). In order to bind to classes, the ActiveRecord mixin would need to implement ActiveRecord::Base.proxy_binding as the Mongoid mixin does. For Mongoid, this looks like:

# Only find the latest if we can order by :updated_at
return nil unless fields['updated_at']
only(:_id, :_type, :updated_at).order_by(updated_at: :desc).first

It'd be similar for ActiveRecord. Something like this would work (though it's not optimized):

return nil unless columns.map(&:name).include?('updated_at')
order('updated_at DESC').first
mfunaro commented 9 years ago

Thanks for the responses. @fancyremarker, I did end up doing something very similar to what you suggested to get things working in a fork. I also created an identity for ActiveRecord so that I could use Patient.identify(params[:id])

dblock commented 9 years ago

Looking forward to some pull requests!

danielkummer commented 9 years ago

:+1: on this...

ericgross commented 9 years ago

Would love to see a PR for this :+1: