active_any 0.0.6 → 0.0.7

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: f55edfb43e9d81dba6c9b0614b34db3b2ffe2f6b
4
- data.tar.gz: 7520decd1d49bf940da804fe42ca899f5644c73c
3
+ metadata.gz: 39acdd4989cf8260cd694f9c90c7e1dee0781e90
4
+ data.tar.gz: 8942a09c7523b615a19bc3853141b47fdbfe9d46
5
5
  SHA512:
6
- metadata.gz: 4679db223ffd527f341392d69e4adff8ba0524c4c5441cc116864497e6c37c7f525d78660075c48db29e08e05dccfb7d4e60e11d719accb12ddb9a129830bd44
7
- data.tar.gz: 672f685c5c891eb4b49f36a6335813dfa89c17e0a78471c6aace41a94f51b3adc08483d72497b1c27a2b418dd9d04de9ad0c3cb2cfc1378843fb38a122efabe3
6
+ metadata.gz: a83b242f2d8a25fe53d78b3fe842f01a701cd8bc6a3605dbe097e337484876eafb804f0da660ab2e6cbe37efae74b6242977dff8fb6a3bad1bb0bf3df07a09bf
7
+ data.tar.gz: e60bc3993222d390e5d2d0b779fe94075d6abfa43f52bd3892c5443a4147a25f475afcea7fd3e6ca30eb48f073ed47a1bc6b33c12cfaecb571f089a87f8f065a
@@ -13,6 +13,15 @@ Style/Documentation:
13
13
  Style/PredicateName:
14
14
  Enabled: false
15
15
 
16
+ Style/AccessorMethodName:
17
+ Enabled: false
18
+
19
+ Metrics/ClassLength:
20
+ Max: 120
21
+
22
+ Metrics/MethodLength:
23
+ Max: 15
24
+
16
25
  Metrics/LineLength:
17
26
  Max: 150
18
27
  Exclude:
@@ -13,6 +13,7 @@ require 'active_any/association_relation'
13
13
  require 'active_any/attribute_assignment'
14
14
  require 'active_any/finders'
15
15
  require 'active_any/core'
16
+ require 'active_any/relation/delegation'
16
17
  require 'active_any/base'
17
18
  require 'active_any/subscriber'
18
19
  require 'active_any/adapters/abstract_adapter'
@@ -45,7 +45,7 @@ module ActiveAny
45
45
  association = association_instance_get(name)
46
46
 
47
47
  if association.nil?
48
- reflection = self.class.reflections[name.to_s]
48
+ reflection = self.class._reflect_on_association(name)
49
49
  raise AssociationNotFoundError.new(self, name) unless reflection
50
50
 
51
51
  association = reflection.association_class.new(self, reflection)
@@ -87,7 +87,7 @@ module ActiveAny
87
87
  end
88
88
  end
89
89
 
90
- def preloader_for(reflection, owners, rhs_klass) # rubocop:disable Metrics/MethodLength
90
+ def preloader_for(reflection, owners, rhs_klass)
91
91
  return NullPreloader unless rhs_klass
92
92
 
93
93
  if owners.first.association(reflection.name).loaded?
@@ -105,9 +105,7 @@ module ActiveAny
105
105
  # scope.joins!(reflection_scope.joins_values)
106
106
  # end
107
107
  order_values = preload_values[:order] || values[:order]
108
- if order_values
109
- scope.order!(order_values)
110
- end
108
+ scope.order!(order_values) if order_values
111
109
 
112
110
  # if preload_values[:reordering] || values[:reordering]
113
111
  # scope.reordering_value = true
@@ -17,7 +17,7 @@ module ActiveAny
17
17
  end
18
18
 
19
19
  def owner_key_name
20
- reflection.primary_key
20
+ reflection.record_class_primary_key
21
21
  end
22
22
  end
23
23
  end
@@ -5,6 +5,8 @@ require 'pathname'
5
5
 
6
6
  module ActiveAny
7
7
  class Base
8
+ extend Delegation::DelegateCache
9
+
8
10
  include Core
9
11
  include Attribute
10
12
  include Associations
@@ -16,10 +18,6 @@ module ActiveAny
16
18
  class Object < Base
17
19
  self.abstract_class = true
18
20
 
19
- def self.inherited(child)
20
- child.abstract_class = false
21
- end
22
-
23
21
  class << self
24
22
  attr_accessor :data
25
23
 
@@ -5,9 +5,7 @@ module ActiveAny
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- class_attribute :abstract_class, instance_writer: false
9
8
  class_attribute :primary_key, instance_writer: false
10
- self.abstract_class = true
11
9
  self.primary_key = nil
12
10
  end
13
11
 
@@ -16,6 +14,8 @@ module ActiveAny
16
14
  end
17
15
 
18
16
  module ClassMethods
17
+ attr_accessor :abstract_class
18
+
19
19
  def unscoped
20
20
  # TODO: implement
21
21
  all
@@ -25,6 +25,18 @@ module ActiveAny
25
25
  # TODO: implement
26
26
  all
27
27
  end
28
+
29
+ def new(*args, &block)
30
+ if abstract_class? || self == Base
31
+ raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
32
+ end
33
+
34
+ super
35
+ end
36
+
37
+ def abstract_class?
38
+ defined?(@abstract_class) && abstract_class == true
39
+ end
28
40
  end
29
41
 
30
42
  def initialize(*args)
@@ -45,11 +45,13 @@ module ActiveAny
45
45
  end
46
46
 
47
47
  def self.add_reflection(klass, name, reflection)
48
- klass.reflections = klass.reflections.merge(name.to_s => reflection)
48
+ klass._reflections = klass.reflections.merge(name.to_s => reflection)
49
49
  end
50
50
 
51
- def self._reflect_on_association(association)
52
- _reflections[association.to_s]
51
+ module ClassMethods
52
+ def _reflect_on_association(association)
53
+ _reflections[association.to_s]
54
+ end
53
55
  end
54
56
  end
55
57
  end
@@ -50,10 +50,6 @@ module ActiveAny
50
50
  @foreign_key ||= options[:foreign_key] || derive_foreign_key.freeze
51
51
  end
52
52
 
53
- def primary_key
54
- @primary_key ||= options[:primary_key] || primary_key_for_record_class
55
- end
56
-
57
53
  def scope_for(klass)
58
54
  scope ? klass.unscoped.instance_exec(nil, &scope) : klass.unscoped
59
55
  end
@@ -77,8 +73,16 @@ module ActiveAny
77
73
  @inverse_of ||= klass._reflect_on_association inverse_name
78
74
  end
79
75
 
76
+ def record_class_primary_key
77
+ @primary_key ||= options[:primary_key] || primary_key(record_class)
78
+ end
79
+
80
80
  private
81
81
 
82
+ def primary_key(record_class)
83
+ record_class.primary_key || (raise UnknownPrimaryKey.new, klass)
84
+ end
85
+
82
86
  def inverse_name
83
87
  options.fetch(:inverse_of) do
84
88
  @automatic_inverse_of ||= automatic_inverse_of
@@ -87,7 +91,7 @@ module ActiveAny
87
91
 
88
92
  def automatic_inverse_of
89
93
  if can_find_inverse_of_automatically?(self)
90
- inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
94
+ inverse_name = ActiveSupport::Inflector.underscore(options[:as] || record_class.name.demodulize).to_sym
91
95
 
92
96
  begin
93
97
  reflection = klass._reflect_on_association(inverse_name)
@@ -97,9 +101,7 @@ module ActiveAny
97
101
  reflection = false
98
102
  end
99
103
 
100
- if valid_inverse_reflection?(reflection)
101
- return inverse_name
102
- end
104
+ return inverse_name if valid_inverse_reflection?(reflection)
103
105
  end
104
106
 
105
107
  false
@@ -129,10 +131,6 @@ module ActiveAny
129
131
  raise NotImplementedError
130
132
  end
131
133
 
132
- def primary_key_for_record_class
133
- klass.primary_key || (raise UnknownPrimaryKey.new, klass)
134
- end
135
-
136
134
  def derive_class_name
137
135
  class_name = name.to_s
138
136
  class_name = class_name.singularize if collection?
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'active_any/relation/finder_methods'
4
4
  require 'active_any/relation/query_methods'
5
+ require 'active_any/relation/delegation'
5
6
  require 'active_any/relation/merger'
6
7
  require 'active_any/relation/where_clause'
7
8
  require 'active_any/relation/order_clause'
@@ -15,11 +16,16 @@ module ActiveAny
15
16
  include Enumerable
16
17
  include FinderMethods
17
18
  include QueryMethods
19
+ include Delegation
18
20
 
19
21
  class ImmutableRelation < StandardError; end
20
22
 
21
23
  def self.create(klass, *args)
22
- new(klass, *args)
24
+ relation_class_for(klass).new(klass, *args)
25
+ end
26
+
27
+ def self.relation_class_for(klass)
28
+ klass.relation_delegate_class(self)
23
29
  end
24
30
 
25
31
  def initialize(klass)
@@ -85,6 +91,22 @@ module ActiveAny
85
91
  false
86
92
  end
87
93
 
94
+ def scoping
95
+ # previous, klass.current_scope = klass.current_scope, self
96
+ yield
97
+ # ensure
98
+ # klass.current_scope = previous
99
+ end
100
+
101
+ def inspect
102
+ subject = loaded? ? records : self
103
+ entries = subject.take([limit_value, 11].compact.min).map!(&:inspect)
104
+
105
+ entries[10] = '...' if entries.size == 11
106
+
107
+ "#<#{self.class.name} [#{entries.join(', ')}]>"
108
+ end
109
+
88
110
  private
89
111
 
90
112
  def spawn
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Delegation
5
+ extend ActiveSupport::Concern
6
+
7
+ module DelegateCache
8
+ def relation_delegate_class(klass)
9
+ @relation_delegate_cache[klass]
10
+ end
11
+
12
+ def initialize_relation_delegate_cache
13
+ @relation_delegate_cache = cache = {}
14
+ [
15
+ ActiveAny::Relation,
16
+ ActiveAny::Associations::CollectionProxy,
17
+ ActiveAny::AssociationRelation
18
+ ].each do |klass|
19
+ delegate = Class.new(klass) { include ClassSpecificRelation }
20
+ mangled_name = klass.name.gsub('::', '_')
21
+ const_set mangled_name, delegate
22
+ private_constant mangled_name
23
+
24
+ cache[klass] = delegate
25
+ end
26
+ end
27
+
28
+ def inherited(child_class)
29
+ child_class.initialize_relation_delegate_cache
30
+ super
31
+ end
32
+ end
33
+
34
+ module ClassSpecificRelation
35
+ extend ActiveSupport::Concern
36
+
37
+ included do
38
+ @delegation_mutex = Mutex.new
39
+ end
40
+
41
+ module ClassMethods
42
+ def name
43
+ superclass.name
44
+ end
45
+
46
+ def delegate_to_scoped_klass(method)
47
+ @delegation_mutex.synchronize do
48
+ return if method_defined?(method)
49
+
50
+ if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
51
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
52
+ def #{method}(*args, &block)
53
+ scoping { @klass.#{method}(*args, &block) }
54
+ end
55
+ RUBY
56
+ else
57
+ define_method method do |*args, &block|
58
+ scoping { @klass.public_send(method, *args, &block) }
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def delegate(method, opts = {})
65
+ @delegation_mutex.synchronize do
66
+ return if method_defined?(method)
67
+ super
68
+ end
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def method_missing(method, *args, &block)
75
+ if @klass.respond_to?(method)
76
+ self.class.delegate_to_scoped_klass(method)
77
+ scoping { @klass.public_send(method, *args, &block) }
78
+ else
79
+ super
80
+ end
81
+ end
82
+
83
+ def respond_to_missing?(name, include_private)
84
+ super
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveAny
4
- VERSION = '0.0.6'
4
+ VERSION = '0.0.7'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_any
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - yuemori
@@ -226,6 +226,7 @@ files:
226
226
  - lib/active_any/reflection/belongs_to_reflection.rb
227
227
  - lib/active_any/reflection/has_many_reflection.rb
228
228
  - lib/active_any/relation.rb
229
+ - lib/active_any/relation/delegation.rb
229
230
  - lib/active_any/relation/finder_methods.rb
230
231
  - lib/active_any/relation/merger.rb
231
232
  - lib/active_any/relation/order_clause.rb