smart_collection 0.0.1 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 206884a5b82cfb9a32a8084b9e28602e0d06aef1
4
- data.tar.gz: 4cfc1bd05e9b4e49d026e3388bb1409b9b92f1db
3
+ metadata.gz: 9f479b5262f4acf4557bce9c9afaefdd07c4c204
4
+ data.tar.gz: a1c9524cfad044566fae79aa21a6bb2286c581bf
5
5
  SHA512:
6
- metadata.gz: e8f54ca5265ded99d18f0a41036fde1fb2052d6c1c26662482b409ecb7c9689bf14bd08f09fa9e10a7fa1cec331c979f88165e79d4fd1d7db0c52b7da5843599
7
- data.tar.gz: de95c2aabb00d01f30fc5f60b826d2b8071d9ecd04e76a245466845a3d9f0a31a927bfc0db9d602ea12b100c8a81e916ad25044684e352c6423032c63ef461a7
6
+ metadata.gz: 21811df6d87e734e1565ea5f29c665e1057ca8f7206e1f53b71582d74c35ed821637eff906d5bb5d430d52c366024377c7829ecf48de3a86bf5f631a3e9a67d0
7
+ data.tar.gz: b92c5993149a07987a08bfa22826334611fd5cdc9fd7970daa5a3f321d340a6bbe9f62cd8a316a2eeafb3daad818cd99bc6a2fe00a7df9cd64ce6cd9bba8c1ff
@@ -3,11 +3,11 @@ module SmartCollection
3
3
  module Preloader
4
4
  class SmartCollectionCachedByTable < ActiveRecord::Associations::Preloader::HasManyThrough
5
5
  def through_reflection
6
- owners.first.class.reflect_on_association(:cached_items)
6
+ reflection.active_record.reflect_on_association(:cached_items)
7
7
  end
8
8
 
9
9
  def source_reflection
10
- association_name = reflection.options[:smart_collection].items_name.to_s.singularize.to_sym
10
+ association_name = reflection.options[:smart_collection].item_name
11
11
  through_reflection.klass.reflect_on_association(association_name)
12
12
  end
13
13
 
@@ -15,43 +15,34 @@ module SmartCollection
15
15
  owners.reject(&:cache_exists?).each(&:update_cache)
16
16
  super
17
17
  end
18
-
19
- private
20
-
21
18
  end
22
19
 
23
20
  class SmartCollectionCachedByCacheStore < ActiveRecord::Associations::Preloader::CollectionAssociation
24
21
  def associated_records_by_owner preloader
25
22
  owners.reject(&:cache_exists?).each(&:update_cache)
26
- loaded = reflection.options[:smart_collection].cache_manager.read_multi(owners)
27
- records = reflection.options[:smart_collection].item_class.where(id: loaded.values.flatten.uniq).map{|x| [x.id, x]}.to_h
23
+ config = reflection.options[:smart_collection]
24
+ loaded = config.cache_manager.read_multi(owners)
25
+ records = config.item_class.where(id: loaded.values.flatten.uniq).map{|x| [x.id, x]}.to_h
28
26
  loaded.map do |owner, ids|
29
27
  [owner, ids.map{|x| records[x]}]
30
28
  end
31
29
  end
32
-
33
- def preload(preloader)
34
- associated_records_by_owner(preloader).each do |owner, records|
35
- association = owner.association(reflection.name)
36
- association.loaded!
37
- association.target.concat(records)
38
- end
39
- end
40
30
  end
31
+
41
32
  end
42
33
  end
43
34
 
44
35
  module ActiveRecordPreloaderPatch
45
36
  def preloader_for(reflection, owners, rhs_klass)
46
- if reflection.options[:smart_collection]
47
- unless reflection.options[:smart_collection].cache_manager
48
- raise RuntimeError, "Turn on cache to enable preloading."
49
- end
50
- case reflection.options[:smart_collection].cache_manager
37
+ config = reflection.options[:smart_collection]
38
+ if config
39
+ case config.cache_manager
51
40
  when SmartCollection::CacheManager::CacheStore
52
41
  SmartCollection::Associations::Preloader::SmartCollectionCachedByCacheStore
53
42
  when SmartCollection::CacheManager::Table
54
43
  SmartCollection::Associations::Preloader::SmartCollectionCachedByTable
44
+ else
45
+ raise RuntimeError, "Turn on cache to enable preloading."
55
46
  end
56
47
  else
57
48
  super
@@ -67,7 +67,7 @@ module SmartCollection
67
67
  end
68
68
 
69
69
  def cached_scope
70
- reflection.options[:smart_collection].cache_manager.read owner
70
+ reflection.options[:smart_collection].cache_manager.read_scope owner
71
71
  end
72
72
 
73
73
  end
@@ -2,12 +2,18 @@ module SmartCollection
2
2
  class CacheManager
3
3
  class CacheStore < CacheManager
4
4
 
5
+ def initialize model:, config:
6
+ super
7
+
8
+ @cache_key_proc = @config.cache_config[:cache_key_proc] || -> (owner) { "_smart_collection_#{owner.class.name}_#{owner.id}" }
9
+ end
10
+
5
11
  def cache_store
6
12
  @config.cache_config[:cache_store]
7
13
  end
8
14
 
9
15
  def cache_key owner
10
- "_smart_collection_#{owner.class.name}_#{owner.id}"
16
+ @cache_key_proc.(owner)
11
17
  end
12
18
 
13
19
  def update owner
@@ -17,7 +23,7 @@ module SmartCollection
17
23
  owner.update(cache_expires_at: Time.now + expires_in)
18
24
  end
19
25
 
20
- def read owner
26
+ def read_scope owner
21
27
  @config.item_class.where(id: Marshal.load(cache_store.read(cache_key owner)))
22
28
  end
23
29
 
@@ -30,7 +36,7 @@ module SmartCollection
30
36
  end
31
37
 
32
38
  def cache_exists? owner
33
- !(owner.cache_expires_at.nil? || owner.cache_expires_at < Time.now) && cache_store.exist?(cache_key owner)
39
+ owner.cache_expires_at && owner.cache_expires_at > Time.now && cache_store.exist?(cache_key owner)
34
40
  end
35
41
 
36
42
  end
@@ -9,17 +9,17 @@ module SmartCollection
9
9
  end
10
10
 
11
11
  def define_cache_association_for model
12
- options = @config.raw_config
12
+ config = @config
13
13
  cached_item_model = nil
14
14
  model.class_eval do
15
15
  cached_item_model = Class.new ActiveRecord::Base do
16
16
  self.table_name = 'smart_collection_cached_items'
17
- belongs_to options[:items].to_s.singularize.to_sym, class_name: options[:class_name], foreign_key: :item_id
17
+ belongs_to config.item_name, class_name: config.item_class_name, foreign_key: :item_id
18
18
  end
19
19
  const_set("CachedItem", cached_item_model)
20
20
 
21
21
  has_many :cached_items, class_name: cached_item_model.name, foreign_key: :collection_id
22
- has_many "cached_#{options[:items]}".to_sym, class_name: options[:class_name], through: :cached_items, source: options[:items].to_s.singularize.to_sym
22
+ has_many "cached_#{config.items_name}".to_sym, class_name: config.item_class_name, through: :cached_items, source: config.item_name
23
23
  end
24
24
  @cache_model = cached_item_model
25
25
  end
@@ -29,16 +29,16 @@ module SmartCollection
29
29
 
30
30
  @cache_model.where(collection_id: owner.id).delete_all
31
31
  @cache_model.connection.execute "INSERT INTO #{@cache_model.table_name} (collection_id, item_id) #{association.uncached_scope.select(owner.id, :id).to_sql}"
32
- owner.update(cache_expires_at: Time.now + expires_in)
32
+ owner.update_column(:cache_expires_at, Time.now + expires_in)
33
33
  end
34
34
 
35
- def read owner
35
+ def read_scope owner
36
36
  cache_association = owner.association("cached_#{@config.items_name}")
37
37
  cache_association.scope
38
38
  end
39
39
 
40
40
  def cache_exists? owner
41
- !(owner.cache_expires_at.nil? || owner.cache_expires_at < Time.now)
41
+ owner.cache_expires_at && owner.cache_expires_at > Time.now
42
42
  end
43
43
 
44
44
  end
@@ -19,7 +19,11 @@ module SmartCollection
19
19
  raise NotImplementedError
20
20
  end
21
21
 
22
- def read owner
22
+ def read_scope owner
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def cache_exists? owner
23
27
  raise NotImplementedError
24
28
  end
25
29
 
@@ -11,12 +11,16 @@ module SmartCollection
11
11
  @raw_config[:items]
12
12
  end
13
13
 
14
+ def item_name
15
+ items_name.to_s.singularize.to_sym
16
+ end
17
+
14
18
  def item_class_name
15
- @raw_config[:item_class]
19
+ @raw_config[:class_name]
16
20
  end
17
21
 
18
22
  def item_class
19
- item_class_name.constantize
23
+ @item_class ||= item_class_name.constantize
20
24
  end
21
25
 
22
26
  def cache_config
@@ -14,7 +14,13 @@ module SmartCollection
14
14
  end
15
15
 
16
16
  def smart_collection_mixin
17
- @__smart_collection_mixin ||= self.class.ancestors.find do |x|
17
+ self.class.smart_collection_mixin
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ def smart_collection_mixin
23
+ @__smart_collection_mixin ||= ancestors.find do |x|
18
24
  x.instance_of? Mixin
19
25
  end
20
26
  end
@@ -22,24 +28,23 @@ module SmartCollection
22
28
 
23
29
  attr_reader :config
24
30
 
25
- def initialize items:, item_class: nil, cached_by: nil
26
- @raw_config = {
27
- items: items,
28
- item_class: item_class,
29
- cached_by: cached_by
30
- }
31
+ def initialize raw_config
32
+ @raw_config = raw_config
31
33
  end
32
34
 
33
35
  def included base
34
- COLLECTIONS[base] = true
35
36
  @config = config = SmartCollection::Config.new(@raw_config)
36
- name = config.items_name
37
37
 
38
- options = {smart_collection: config}
39
- options[:class_name] = config.item_class_name if config.item_class_name
40
- reflection = Builder::SmartCollectionAssociation.build(base, name, nil, options)
41
- ::ActiveRecord::Reflection.add_reflection base, name, reflection
38
+ reflection_options = {smart_collection: config}
39
+ if config.item_class_name
40
+ reflection_options[:class_name] = config.item_class_name
41
+ end
42
+
43
+ reflection = Builder::SmartCollectionAssociation.build(base, config.items_name, nil, reflection_options)
44
+ ::ActiveRecord::Reflection.add_reflection base, config.items_name, reflection
45
+
42
46
  base.include(InstanceMethods)
47
+ base.extend(ClassMethods)
43
48
 
44
49
  if cache_class = CacheManager.determine_class(@raw_config)
45
50
  config.cache_manager = cache_class.new(model: base, config: config)
@@ -6,7 +6,14 @@ module SmartCollection
6
6
  end
7
7
 
8
8
  def check_eager_loadable!
9
- raise RuntimeError, 'eager_load is not supported by now.'
9
+ unless options[:smart_collection].cache_manager.instance_of? SmartCollection::CacheManager::Table
10
+ raise RuntimeError, 'eager_load is only supported when using table for cache.'
11
+ end
12
+ end
13
+
14
+ def chain
15
+ items_name = options[:smart_collection].items_name
16
+ active_record.reflect_on_association("cached_#{items_name}".to_sym).chain
10
17
  end
11
18
  end
12
19
  end
@@ -0,0 +1,3 @@
1
+ module SmartCollection
2
+ VERSION = '0.1'
3
+ end
@@ -1,9 +1,5 @@
1
1
  require 'active_record'
2
2
 
3
- module SmartCollection
4
- COLLECTIONS = {}
5
- end
6
-
7
3
  Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").each do |file|
8
4
  require file
9
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_collection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - CicholGricenchos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-08 00:00:00.000000000 Z
11
+ date: 2018-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '5'
22
+ version: '6.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - ">"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '5'
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: pry
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +72,20 @@ dependencies:
66
72
  - - ">="
67
73
  - !ruby/object:Gem::Version
68
74
  version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
69
89
  description: ''
70
90
  email:
71
91
  - cichol@live.cn
@@ -83,6 +103,7 @@ files:
83
103
  - lib/smart_collection/config.rb
84
104
  - lib/smart_collection/mixin.rb
85
105
  - lib/smart_collection/reflection/smart_collection_reflection.rb
106
+ - lib/smart_collection/version.rb
86
107
  homepage: https://github.com/CicholGricenchos/smart_collection
87
108
  licenses:
88
109
  - MIT
@@ -106,5 +127,5 @@ rubyforge_project:
106
127
  rubygems_version: 2.5.2.1
107
128
  signing_key:
108
129
  specification_version: 4
109
- summary: ''
130
+ summary: collections by rules
110
131
  test_files: []