taggable_cache 0.4.2 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cdaec20312f2c8794e73619e4abb0a2e2c7b3510
4
+ data.tar.gz: 8c3793e1730ea5081398435d07d725b1d688f9ed
5
+ SHA512:
6
+ metadata.gz: 0f209d642abb7b5d4f1d8d920aae6b1ef1439ca248008e17b22c5d92a5f5ea8971eaf681185bc8ec4dd8225a34c4c989650c4086ea463b6f3c0ddfc1a223e36a
7
+ data.tar.gz: 16ef5e005b31351642da8a4953840c56c2ab432bec26103ccf2373f29a4907e88ad0ff29523008ec5363d7f5eea02e4f50aa727728a41e4d56d5178c60cfbc71
@@ -1,11 +1,24 @@
1
1
  language: ruby
2
- bundler_args: --without development
2
+
3
+ before_install:
4
+ - mkdir -p tmp/cache
5
+ - mkdir -p spec/internal/db
6
+ - memcached -p 11212 &
7
+
8
+ services:
9
+ - redis-server
10
+
3
11
  rvm:
4
12
  - 1.9.3
13
+ - 2.0.0
14
+
5
15
  gemfile:
6
16
  - gemfiles/Gemfile-rails.3.1.x
7
17
  - gemfiles/Gemfile-rails.3.2.x
18
+
8
19
  env:
9
20
  - CACHE_STORE=redis
10
21
  - CACHE_STORE=memcached
11
- - CACHE_STORE=file_store
22
+ - CACHE_STORE=file_store
23
+ - CACHE_STORE=memory_store
24
+ - CACHE_STORE=dalli
@@ -1,3 +1,9 @@
1
+ = Taggable cache 0.5
2
+ - String can be used as key for expiration
3
+ - Add support for multiple tag store backends
4
+ - Namespaced cache keys support
5
+ - Ruby 2.0 support
6
+
1
7
  = Taggable cache 0.4.2
2
8
 
3
9
  - Internal refactoring
@@ -1,10 +1,9 @@
1
- = Taggable cache
1
+ = Taggable cache {<img src="https://secure.travis-ci.org/brain-geek/taggable-cache.png"/>}[http://travis-ci.org/brain-geek/taggable-cache]
2
2
 
3
- This gem simplifies cache expiration in rails by adding depends_on helper, which expires cache element when depending object is changed/deleted.
3
+ This gem simplifies cache expiration in rails by adding depends_on parameter to rails cache setting, which makes cache element expire when depending object is changed.
4
4
 
5
- = Build Status {<img src="https://secure.travis-ci.org/brain-geek/taggable-cache.png"/>}[http://travis-ci.org/brain-geek/taggable-cache]
6
5
  = How to use
7
- For taggable-cache you must have redis server for data about tags. Cache storage can be anything, but gem uses redis for its own storage.
6
+ Taggable-cache uses redis to store cache tags data. You can use anything for an actual cache storage. {RDoc}[http://rdoc.info/github/brain-geek/taggable-cache/master/frames]
8
7
 
9
8
  Controller(action caching):
10
9
 
@@ -13,22 +12,22 @@ Controller(action caching):
13
12
  def index
14
13
  Page.load_lot_of_data
15
14
 
16
- #this depends on any Page object change - creation, deletion, change
15
+ #this depends on any Page object change - creation, deletion, update
17
16
  depends_on Page
18
17
  end
19
18
 
20
19
  View(fragment caching):
21
20
 
22
21
  <%# Page.active can be AR scope, every Page object on change is checked if it is in this scope, and if is - expires cache element %>
23
- <% cache 'cache_entry', :depends_on => [Page.active] do %>
22
+ <% cache 'cache_entry', :depends_on => Page.active do %>
24
23
  <% Page.load_lot_of_data %>
25
24
  <% end %>
26
25
 
27
26
  Usage with Rails.cache:
28
27
 
29
28
  page = Page.first
30
- #this cache key expires only if this Page object is changed/deleted
31
- Rails.cache.write('key', 'value', :depends_on => [page])
29
+ #this cache key expires only when this Page object is changed/deleted
30
+ Rails.cache.write('key', 'value', :depends_on => page)
32
31
 
33
32
  Usage with cells gem:
34
33
 
@@ -42,14 +41,31 @@ Usage with cells gem:
42
41
 
43
42
  If you are using redis for cache, it is recommended to set default expire_ttl value:
44
43
 
45
- config.cache_store = ActiveSupport::Cache::RedisStore.new(:expire_in => 16.hours.to_i)
44
+ config.cache_store = ActiveSupport::Cache::RedisStore.new(:expire_in => 16.hours.to_i)
46
45
 
47
46
  == What is supported
48
47
 
49
- Rails 3.1.x and 3.2.x are supported. Tested with ruby 1.9.3, but should work on 1.8.7. As cache storage you can use redis, memcached and file store caches.
48
+ Rails 3.1.x and 3.2.x are both supported. Tested with ruby 1.9.3. Cache storage engines tested:
49
+ - {redis}[https://github.com/jodosha/redis-store]
50
+ - {dalli}[https://github.com/mperham/dalli]
51
+ - {memcached-client}[https://github.com/mperham/memcache-client]
52
+ - Rails file store
53
+ - Rails memory store
54
+
55
+ Other cache storages should work but have not been tested by author.
56
+
57
+ == Customizing store backend options
58
+
59
+ You can set custom host/port or store in taggable:
60
+
61
+ TaggableCache.settings = {
62
+ :store => :redis,
63
+ :host => '127.0.0.1',
64
+ :port => 6379
65
+ }
50
66
 
51
67
  == Contributing to taggable-cache
52
-
68
+
53
69
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
54
70
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
55
71
  * Fork the project.
@@ -60,4 +76,3 @@ Rails 3.1.x and 3.2.x are supported. Tested with ruby 1.9.3, but should work on
60
76
  == Copyright
61
77
 
62
78
  Copyright (c) 2012 Alex Rozumey. See LICENSE.txt for further details.
63
-
@@ -4,7 +4,8 @@ gem 'rake'
4
4
  gem 'rspec-rails', :require => false
5
5
  gem 'rspec'
6
6
  gem 'capybara'
7
- gem "combustion", "~> 0.3.2"
7
+ gem "combustion", "=0.3.2"
8
8
  gem 'sqlite3'
9
9
 
10
- gem 'memcache-client'
10
+ gem 'memcache-client'
11
+ gem 'dalli'
@@ -1,6 +1,25 @@
1
1
  require 'rails'
2
2
 
3
3
  module TaggableCache
4
+ def settings
5
+ @@settings ||= {:store => :redis, :host => '127.0.0.1', :port => 6379}
6
+ end
7
+
8
+ def settings=(value)
9
+ @@settings = value
10
+ end
11
+
12
+ # Creates new Taggable store instance based on current settings
13
+ def new_store
14
+ params = settings.dup
15
+ params.delete(:store)
16
+
17
+ cls = Store::const_get(settings[:store].to_s.camelize)
18
+
19
+ cls.send(:new, params)
20
+ end
21
+
22
+ extend self
4
23
  end
5
24
 
6
25
  require 'taggable_cache/store'
@@ -1,25 +1,20 @@
1
1
  module TaggableCache
2
2
  module ActionControllerExtension
3
- extend ActiveSupport::Concern
4
- def self.included(base)
5
- base.class_eval do
6
- def depends_on(*keys)
7
- _process_action_callbacks.find_all{|x|
8
- (x.kind == :around) &&
9
- (x.raw_filter.is_a? ActionController::Caching::Actions::ActionCacheFilter) }.each do |callback|
10
- cache_path = callback.raw_filter.instance_variable_get('@cache_path')
3
+ def depends_on(*keys)
4
+ _process_action_callbacks.find_all{|x|
5
+ (x.kind == :around) &&
6
+ (x.raw_filter.is_a? ActionController::Caching::Actions::ActionCacheFilter) }.each do |callback|
7
+ cache_path = callback.raw_filter.instance_variable_get('@cache_path')
11
8
 
12
- path_options = if cache_path.respond_to?(:call)
13
- instance_exec(self, &cache_path)
14
- else
15
- cache_path
16
- end
9
+ path_options = if cache_path.respond_to?(:call)
10
+ instance_exec(self, &cache_path)
11
+ else
12
+ cache_path
13
+ end
17
14
 
18
- path_options = ::ActionController::Caching::Actions::ActionCachePath.new(self, path_options || {}).path
15
+ path_options = ::ActionController::Caching::Actions::ActionCachePath.new(self, path_options || {}).path
19
16
 
20
- Rails.cache.add_tags(fragment_cache_key(path_options), *keys)
21
- end
22
- end
17
+ Rails.cache.add_tags(fragment_cache_key(path_options), *keys)
23
18
  end
24
19
  end
25
20
  end
@@ -1,16 +1,15 @@
1
1
  module TaggableCache
2
2
  module ActiveRecordExtension
3
3
  extend ActiveSupport::Concern
4
- included do
5
- # Future subclasses will pick up the model extension
6
- class << self
7
- def inherited_with_taggable(kls)
8
- inherited_without_taggable kls
9
- kls.send(:include, TaggableCache::ActiveRecordModelExtension) if kls.superclass == ActiveRecord::Base
10
- end
11
- alias_method_chain :inherited, :taggable
12
- end
13
4
 
5
+ module ClassMethods
6
+ def inherited(kls)
7
+ kls.send(:include, TaggableCache::ActiveRecordModelExtension) if kls.superclass == ActiveRecord::Base
8
+ super
9
+ end
10
+ end
11
+
12
+ included do
14
13
  # Existing subclasses pick up the model extension as well
15
14
  self.descendants.each do |kls|
16
15
  kls.send(:include, TaggableCache::ActiveRecordModelExtension) if kls.superclass == ActiveRecord::Base
@@ -18,13 +17,12 @@ module TaggableCache
18
17
  end
19
18
  end
20
19
 
21
-
22
20
  module ActiveRecordModelExtension
23
21
  extend ActiveSupport::Concern
24
22
  def self.included(base)
25
23
  [:after_update, :before_update, :before_destroy, :after_create].each do |event|
26
24
  base.send(event, Proc.new do |model|
27
- Rails.cache.delete_by_tags(model, model.class)
25
+ Rails.cache.expire_tags(model, model.class)
28
26
  end)
29
27
  end
30
28
  end
@@ -1,55 +1,63 @@
1
1
  module TaggableCache
2
2
  module CacheStoreExtension
3
3
  extend ActiveSupport::Concern
4
- def self.included(base)
5
- base.class_eval do
6
- def taggable
7
- @taggable ||= ::TaggableCache::Store::Redis.new
8
- end
9
-
10
- def write_with_taggable(name, value, options = nil)
11
- if !options.nil? && options.has_key?(:depends_on)
12
- add_tags(name, *options[:depends_on])
13
- end
14
4
 
15
- write_without_taggable(name, value, options)
16
- end
5
+ def taggable
6
+ @taggable ||= TaggableCache.new_store
7
+ end
17
8
 
18
- alias_method_chain :write, :taggable
9
+ # Add tag to cache element
10
+ def add_tags(key, *params)
11
+ taggable.add(key, *params)
12
+ end
19
13
 
20
- def add_tags(key, *params)
21
- taggable.add(key, *params)
22
- end
14
+ # Expire cache elements by list of keys
15
+ def expire_tags(*params)
16
+ taggable.get(*params).each do |m|
17
+ self.delete(m)
18
+ end
19
+ end
23
20
 
24
- def delete_by_tags(*params)
25
- taggable.get(*params).each do |m|
26
- self.delete(m)
27
- end
21
+ # Expire all cache entries availible for taggable
22
+ # WARNING: this is expensive function and may take VERY long on big data
23
+ def expire_all
24
+ #Load all the models
25
+ Dir.glob(Rails.root + '/app/models/*.rb').each {|file| require file}
26
+
27
+ ActiveRecord::Base.subclasses.each do |cls|
28
+ expire_tags cls
28
29
 
29
- taggable.get_scope(*(params.delete_if{|a| not a.is_a? ActiveRecord::Base})).each do |m|
30
- self.delete(m)
31
- end
32
- end
30
+ pk_name = cls.primary_key
33
31
 
34
- def expire_all
35
- #Load all the models
36
- Dir.glob(Rails.root + '/app/models/*.rb').each {|file| require file}
37
-
38
- ActiveRecord::Base.subclasses.each do |cls|
39
- delete_by_tags cls
32
+ return if cls.unscoped.first.nil? #There is no sence in continuing, if model is empty
40
33
 
41
- pk_name = cls.primary_key
34
+ last_id = cls.order(pk_name).last.try(pk_name.to_sym)
42
35
 
43
- return if cls.unscoped.first.nil? #There is no sence in continuing, if model is empty
36
+ #hardcoded value for first record
37
+ first_id = 1
44
38
 
45
- last_id = cls.order(pk_name).last.try(pk_name.to_sym)
46
- first_id = 1
39
+ (first_id..last_id).each do |id|
40
+ expire_tags({:cls => cls, :id => id})
41
+ end
42
+ end
43
+ end
47
44
 
48
- (first_id..last_id).each do |id|
49
- delete_by_tags({:cls => cls, :id => id})
50
- end
45
+ included do |base|
46
+ base.class_eval do
47
+ # Returns taggable store instance
48
+ def write_with_taggable(name, value, options = {})
49
+ begin
50
+ k = namespaced_key(name, options)
51
+ rescue
52
+ k = name
51
53
  end
54
+
55
+ add_tags(k, *options[:depends_on]) if options.has_key?(:depends_on)
56
+
57
+ write_without_taggable(name, value, options)
52
58
  end
59
+
60
+ alias_method_chain :write, :taggable
53
61
  end
54
62
  end
55
63
  end
@@ -9,8 +9,9 @@ module TaggableCache
9
9
  ::ActiveRecord::Base.send :include, TaggableCache::ActiveRecordExtension
10
10
  ::ActionController::Base.send :include, TaggableCache::ActionControllerExtension
11
11
 
12
- ::ActiveSupport::Cache::Store.send :include, TaggableCache::CacheStoreExtension
12
+ ::ActiveSupport::Cache::DalliStore.send :include, TaggableCache::CacheStoreExtension if defined? ::ActiveSupport::Cache::DalliStore
13
13
  ::ActiveSupport::Cache::RedisStore.send :include, TaggableCache::CacheStoreExtension if defined? ::ActiveSupport::Cache::RedisStore
14
+ ::ActiveSupport::Cache::Store.send :include, TaggableCache::CacheStoreExtension
14
15
  end
15
16
  end
16
17
  end
@@ -1,5 +1,6 @@
1
1
  module TaggableCache::Store
2
2
  class Base
3
+ # Returns taggable cache unique id for object
3
4
  def id_for(obj)
4
5
  if obj.is_a? Class
5
6
  obj.to_s.downcase
@@ -13,6 +14,8 @@ module TaggableCache::Store
13
14
  "query-keys-#{Digest::MD5.hexdigest(obj.to_sql)}"
14
15
  elsif obj.is_a? ActiveRecord::Relation
15
16
  id_for(obj.arel)
17
+ elsif obj.is_a? String
18
+ "string_#{obj.to_s}"
16
19
  elsif obj.is_a? Hash
17
20
  if obj.include?(:cls) && obj.include?(:id)
18
21
  "#{obj[:cls].to_s.downcase}-#{obj[:id]}"
@@ -24,10 +27,12 @@ module TaggableCache::Store
24
27
  end
25
28
  end
26
29
 
30
+ # Checks if this is AR scope
27
31
  def is_scope?(scope)
28
32
  (scope.is_a? ActiveRecord::Relation) || (scope.is_a? Arel::SelectManager)
29
33
  end
30
34
 
35
+ # Checks if object is in given scope
31
36
  def in_scope?(scope, object)
32
37
  return false unless object.persisted?
33
38
 
@@ -36,24 +41,19 @@ module TaggableCache::Store
36
41
  object.class.connection.select_all(query).length > 0
37
42
  end
38
43
 
39
- def initialize
44
+ #:nodoc:
45
+ def initialize(attrs = {})
40
46
  raise ActionController::NotImplemented.new
41
47
  end
42
48
 
49
+ #:nodoc:
43
50
  def add(tag, *members)
44
51
  raise ActionController::NotImplemented.new
45
52
  end
46
53
 
54
+ #:nodoc:
47
55
  def get(*members)
48
56
  raise ActionController::NotImplemented.new
49
57
  end
50
-
51
- def add_scope(tag, scope)
52
- raise ActionController::NotImplemented.new
53
- end
54
-
55
- def get_scope(*members)
56
- raise ActionController::NotImplemented.new
57
- end
58
58
  end
59
59
  end
@@ -3,11 +3,11 @@ require "digest/md5"
3
3
 
4
4
  module TaggableCache::Store
5
5
  class Redis < TaggableCache::Store::Base
6
- def initialize
7
- @redis = ::Redis.new :host => ENV['REDIS_HOST'] || '127.0.0.1',
8
- :port => ENV['REDIS_PORT'] ? ENV['REDIS_PORT'].to_i : 6379
6
+ def initialize(attrs = {})
7
+ @redis = ::Redis.new attrs
9
8
  end
10
9
 
10
+ # Add tag to multiple cache entries
11
11
  def add(tag, *members)
12
12
  members.each do |element|
13
13
  add_scope(tag, element) if is_scope? element
@@ -16,13 +16,24 @@ module TaggableCache::Store
16
16
  end
17
17
  end
18
18
 
19
+ # Get cache entries by given keys.
20
+ # This list is cleaned up after request:
21
+ # page = Page.create
22
+ # store.add('tag_name', page)
23
+ # store.get_scope(p).should == ['tag_name']
24
+ # store.get_scope(p).should == []
19
25
  def get(*members)
20
26
  keys = members.map { |tag| id_for(tag) }
21
27
  elements = @redis.sunion(keys)
22
28
  @redis.del(keys)
23
- elements.flatten.compact
29
+
30
+ scopes = members.delete_if {|a| not a.is_a? ActiveRecord::Base}
31
+
32
+ elements += get_scope(*scopes)
33
+ elements.flatten.uniq.compact
24
34
  end
25
35
 
36
+ protected
26
37
  def add_scope(tag, scope)
27
38
  scope = scope.arel if scope.is_a? ActiveRecord::Relation
28
39
  table_name = scope.froms.first.name
@@ -49,7 +60,7 @@ module TaggableCache::Store
49
60
  end
50
61
  end
51
62
 
52
- keys.flatten.compact
63
+ keys
53
64
  end
54
65
  end
55
66
  end
@@ -1,3 +1,3 @@
1
1
  module TaggableCache
2
- VERSION = "0.4.2" # This is for the gem and does not conflict with the rest of the functionality
2
+ VERSION = "0.5" # This is for the gem and does not conflict with the rest of the functionality
3
3
  end
@@ -2,8 +2,8 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
2
 
3
3
  describe 'TaggableCache::Rails::Cache' do
4
4
  before :all do
5
- @object = TaggableCache::Store::Redis.new
6
- @page_object = Page.create
5
+ @object = TaggableCache.new_store
6
+ @page_object = Page.create!
7
7
  end
8
8
 
9
9
  before :each do
@@ -21,6 +21,16 @@ describe 'TaggableCache::Rails::Cache' do
21
21
  Rails.cache.write 'ipsum', 'lorem'
22
22
  Rails.cache.read('ipsum').should == 'lorem'
23
23
  end
24
+
25
+ it "does expire for namespaced key" do
26
+ Rails.cache.write('key', 'val', :namespace => 'lorem ipsum', :depends_on => @page_object)
27
+
28
+ Rails.cache.read('key', :namespace => 'lorem ipsum').should == 'val'
29
+
30
+ @page_object.save!
31
+
32
+ Rails.cache.read('key', :namespace => 'lorem ipsum').should be_nil
33
+ end
24
34
  end
25
35
 
26
36
  describe "Rails.cache.fetch integration" do
@@ -39,7 +49,6 @@ describe 'TaggableCache::Rails::Cache' do
39
49
 
40
50
  Rails.cache.read('ftch_ipsum').should == 'lorem ipsum'
41
51
 
42
- @page_object.name = 'dfgsdgsdfgsdfg'
43
52
  @page_object.save!
44
53
 
45
54
  Rails.cache.read('ftch_ipsum').should be_nil
@@ -56,6 +65,29 @@ describe 'TaggableCache::Rails::Cache' do
56
65
 
57
66
  Rails.cache.read('ftch_ipsum2').should be_nil
58
67
  end
68
+
69
+ it "does combined expires" do
70
+ page = Page.create!
71
+ Rails.cache.fetch 'ftch_ipsum3', :depends_on => [page, @page_object] do
72
+ 'lorem ipsum di'
73
+ end
74
+
75
+ Rails.cache.read('ftch_ipsum3').should == 'lorem ipsum di'
76
+
77
+ @page_object.save!
78
+
79
+ Rails.cache.read('ftch_ipsum3').should be_nil
80
+
81
+ Rails.cache.fetch 'ftch_ipsum3', :depends_on => [page, @page_object] do
82
+ 'lorem ipsum di'
83
+ end
84
+
85
+ Rails.cache.read('ftch_ipsum3').should == 'lorem ipsum di'
86
+
87
+ page.save!
88
+
89
+ Rails.cache.read('ftch_ipsum3').should be_nil
90
+ end
59
91
  end
60
92
 
61
93
  describe "Activerecord integration" do
@@ -65,7 +97,6 @@ describe 'TaggableCache::Rails::Cache' do
65
97
  Rails.cache.read('key').should == 'value'
66
98
 
67
99
  #save should trigger deleting depending cache entries
68
- @page_object.name = @page_object.name.to_s + '1'
69
100
  @page_object.save!
70
101
 
71
102
  Rails.cache.read('key').should be_nil
@@ -9,12 +9,16 @@ class Combustion::Application
9
9
  when 'redis'
10
10
  config.cache_store = :redis_store
11
11
  when 'memcached'
12
- config.cache_store = :mem_cache_store
12
+ config.cache_store = :mem_cache_store, "127.0.0.1:11212"
13
+ when 'memory_store'
14
+ config.cache_store = :memory_store
15
+ when 'dalli'
16
+ config.cache_store = :dalli_store, '127.0.0.1:11212'
13
17
  when 'file_store'
14
18
  end
15
19
  end
16
20
 
17
- Combustion.initialize!
21
+ Combustion.initialize! :all
18
22
 
19
23
  require 'rspec/rails'
20
24
  require 'capybara/rails'
@@ -1,23 +1,55 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
2
 
3
3
  describe TaggableCache::Store do
4
+ before :all do
5
+ Rails.cache
6
+ @cache_settings = TaggableCache.settings
7
+ end
8
+
4
9
  after :all do
5
- ENV.delete("REDIS_HOST")
6
- ENV.delete("REDIS_PORT")
10
+ TaggableCache.settings = @cache_settings
11
+ end
12
+
13
+ def new_cache_instance
14
+ Rails.cache.class.new({})
15
+ end
16
+
17
+ it "should have default variables" do
18
+ TaggableCache.settings[:store].should == :redis
19
+ TaggableCache.settings[:host].should == '127.0.0.1'
20
+ TaggableCache.settings[:port].should == 6379
7
21
  end
8
22
 
9
23
  it "should fall back to defaults if no settings given" do
24
+ Redis.should_receive(:new) if Rails.cache.is_a? ActiveSupport::Cache::RedisStore
10
25
  Redis.should_receive(:new).with(:host => '127.0.0.1', :port => 6379)
11
26
 
12
- TaggableCache::Store::Redis.new
27
+ new_cache_instance.taggable
13
28
  end
14
29
 
15
30
  it "should use ENV settings" do
16
- ENV["REDIS_HOST"] = 'hostname.lvh.me';
17
- ENV["REDIS_PORT"] = '1234';
31
+ TaggableCache.settings = {
32
+ :store => :redis,
33
+ :host => 'hostname.lvh.me',
34
+ :port => 1234
35
+ }
18
36
 
37
+ Redis.should_receive(:new) if Rails.cache.is_a? ActiveSupport::Cache::RedisStore
19
38
  Redis.should_receive(:new).with(:host => 'hostname.lvh.me', :port => 1234)
20
39
 
21
- TaggableCache::Store::Redis.new
40
+ new_cache_instance.taggable
41
+ end
42
+
43
+ it "should use 'store' option to detect which class to create" do
44
+ TaggableCache.settings = {
45
+ :store => :base,
46
+ :first => 'hostname.lvh.me',
47
+ :second => 1234,
48
+ :third => 'asads'
49
+ }
50
+
51
+ TaggableCache::Store::Base.should_receive(:new).with(:first => 'hostname.lvh.me', :second => 1234, :third => 'asads')
52
+
53
+ new_cache_instance.taggable
22
54
  end
23
55
  end
@@ -4,13 +4,13 @@ describe TaggableCache::Store do
4
4
  describe "connection to redis" do
5
5
  it "should use default settings" do
6
6
  Redis.should_receive(:new)
7
- TaggableCache::Store::Redis.new
7
+ TaggableCache.new_store
8
8
  end
9
9
  end
10
10
 
11
11
  describe "adding tags" do
12
12
  before :all do
13
- @object = TaggableCache::Store::Redis.new
13
+ @object = TaggableCache.new_store
14
14
  @redis = Redis.new
15
15
  @redis.flushall
16
16
  end
@@ -52,6 +52,10 @@ describe TaggableCache::Store do
52
52
  @object.id_for({:id => 543}).should be_nil
53
53
  @object.id_for({:sdfasdf => 345}).should be_nil
54
54
  end
55
+
56
+ it "should allow string values as keys" do
57
+ @object.id_for('lorem').should == 'string_lorem'
58
+ end
55
59
  end
56
60
 
57
61
  describe "is_scope?" do
@@ -100,15 +104,15 @@ describe TaggableCache::Store do
100
104
  @object.in_scope?(Page.order(:id), Page.new).should be_false
101
105
  end
102
106
 
103
- describe "get_scope" do
107
+ describe "get" do
104
108
  it "should return keys and leave nothing behind" do
105
109
  #query to get all keys
106
110
  p = Page.create
107
111
  page = Page.order(:id)
108
112
 
109
113
  @object.add('tag_name', page)
110
- @object.get_scope(p).should == ['tag_name']
111
- @object.get_scope(p).should == []
114
+ @object.get(p).should == ['tag_name']
115
+ @object.get(p).should == []
112
116
  end
113
117
 
114
118
  it "should do multi-get" do
@@ -120,9 +124,32 @@ describe TaggableCache::Store do
120
124
  @object.add('jack', Page.where(:name => 'jack'))
121
125
  @object.add('ian', Page.where(:name => 'ian'))
122
126
 
123
- @object.get_scope(bob,jack).should == ['bob', 'jack']
124
- @object.get_scope(bob,jack).should == []
125
- @object.get_scope(ian).should == ['ian']
127
+ @object.get(bob,jack).should == ['bob', 'jack']
128
+ @object.get(bob,jack).should == []
129
+ @object.get(ian).should == ['ian']
130
+ end
131
+
132
+ it "should be able to mix both scope and simple element results" do
133
+ bob = Page.create(:name => 'bob')
134
+ jack = Page.create(:name => 'jack')
135
+ Page.create(:name => 'ian')
136
+
137
+ @object.add('bob', Page.where(:name => 'bob'))
138
+ @object.add('jack', jack)
139
+
140
+ @object.get(bob,jack).should =~ ['bob', 'jack']
141
+ end
142
+
143
+ it "should not duplicate keys" do
144
+ bob = Page.create(:name => 'bob')
145
+ jack = Page.create(:name => 'jack')
146
+ ian = Page.create(:name => 'ian')
147
+
148
+ @object.add('bob', Page.where('name is NOT NULL'))
149
+ @object.add('jack', Page.where(:name => 'jack'))
150
+ @object.add('ian', Page.where(:name => 'ian'))
151
+
152
+ @object.get(bob,jack,ian).should == ['bob', 'jack', 'ian']
126
153
  end
127
154
  end
128
155
  end
@@ -164,7 +191,7 @@ describe TaggableCache::Store do
164
191
  @redis.smembers("page-#{page.id}").should == ['tag_name']
165
192
  @redis.smembers("page").should == ['tag2']
166
193
 
167
- @object.get(page, Page).should == ['tag_name', 'tag2']
194
+ @object.get(page, Page).should =~ ['tag_name', 'tag2']
168
195
  @redis.smembers("page-#{page.id}").should be_empty
169
196
  @redis.smembers("page").should be_empty
170
197
  end
metadata CHANGED
@@ -1,78 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taggable_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
5
- prerelease:
4
+ version: '0.5'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Alex Rozumey
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-06-30 00:00:00.000000000 Z
11
+ date: 2013-06-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.1.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 3.1.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: actionpack
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: 3.1.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: 3.1.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activerecord
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: 3.1.0
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: 3.1.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: redis
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: 2.2.0
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: 2.2.0
78
69
  description: It makes cache expiration in rails much simpler
@@ -121,32 +112,25 @@ files:
121
112
  homepage: http://github.com/brain-geek/taggable-cache
122
113
  licenses:
123
114
  - MIT
115
+ metadata: {}
124
116
  post_install_message:
125
117
  rdoc_options: []
126
118
  require_paths:
127
119
  - lib
128
120
  required_ruby_version: !ruby/object:Gem::Requirement
129
- none: false
130
121
  requirements:
131
- - - ! '>='
122
+ - - '>='
132
123
  - !ruby/object:Gem::Version
133
124
  version: '0'
134
- segments:
135
- - 0
136
- hash: -997136803
137
125
  required_rubygems_version: !ruby/object:Gem::Requirement
138
- none: false
139
126
  requirements:
140
- - - ! '>='
127
+ - - '>='
141
128
  - !ruby/object:Gem::Version
142
129
  version: '0'
143
- segments:
144
- - 0
145
- hash: -997136803
146
130
  requirements: []
147
131
  rubyforge_project:
148
- rubygems_version: 1.8.24
132
+ rubygems_version: 2.0.3
149
133
  signing_key:
150
- specification_version: 3
134
+ specification_version: 4
151
135
  summary: This gem simplifies cache expiration in rails by expanding rails cache methods.
152
136
  test_files: []