smart_collection 0.0.1 → 0.1

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.
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: []