active_any 0.0.7 → 0.0.8

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/lib/active_any/association_relation.rb +9 -0
  4. data/lib/active_any/associations.rb +10 -0
  5. data/lib/active_any/associations/association.rb +7 -7
  6. data/lib/active_any/associations/belongs_to_association.rb +1 -14
  7. data/lib/active_any/associations/builder/association.rb +14 -8
  8. data/lib/active_any/associations/builder/has_many.rb +4 -12
  9. data/lib/active_any/associations/builder/has_one.rb +15 -0
  10. data/lib/active_any/associations/builder/singular_association.rb +9 -0
  11. data/lib/active_any/associations/collection_proxy.rb +6 -1
  12. data/lib/active_any/associations/foreign_association.rb +13 -0
  13. data/lib/active_any/associations/foreign_key_association.rb +13 -0
  14. data/lib/active_any/associations/has_many_association.rb +3 -1
  15. data/lib/active_any/associations/has_one_association.rb +9 -0
  16. data/lib/active_any/associations/preloader.rb +2 -0
  17. data/lib/active_any/associations/preloader/belongs_to.rb +1 -10
  18. data/lib/active_any/associations/preloader/has_one.rb +17 -0
  19. data/lib/active_any/associations/preloader/singular_association.rb +18 -0
  20. data/lib/active_any/associations/singular_association.rb +17 -0
  21. data/lib/active_any/attribute.rb +4 -0
  22. data/lib/active_any/core.rb +14 -0
  23. data/lib/active_any/reflection.rb +3 -0
  24. data/lib/active_any/reflection/association_reflection.rb +4 -0
  25. data/lib/active_any/reflection/belongs_to_reflection.rb +1 -1
  26. data/lib/active_any/reflection/has_many_reflection.rb +1 -1
  27. data/lib/active_any/reflection/has_one_reflection.rb +33 -0
  28. data/lib/active_any/relation.rb +0 -8
  29. data/lib/active_any/relation/delegation.rb +16 -2
  30. data/lib/active_any/version.rb +1 -1
  31. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39acdd4989cf8260cd694f9c90c7e1dee0781e90
4
- data.tar.gz: 8942a09c7523b615a19bc3853141b47fdbfe9d46
3
+ metadata.gz: a75e1b79e1e6e0f79b2a8d19e730e4a47ddca996
4
+ data.tar.gz: 31cc1c7938c0649d3da04cfcaca9f2a55ff2e558
5
5
  SHA512:
6
- metadata.gz: a83b242f2d8a25fe53d78b3fe842f01a701cd8bc6a3605dbe097e337484876eafb804f0da660ab2e6cbe37efae74b6242977dff8fb6a3bad1bb0bf3df07a09bf
7
- data.tar.gz: e60bc3993222d390e5d2d0b779fe94075d6abfa43f52bd3892c5443a4147a25f475afcea7fd3e6ca30eb48f073ed47a1bc6b33c12cfaecb571f089a87f8f065a
6
+ metadata.gz: cc4a1f10b34b27e3412593e5094e09de8caab31e02e9ff4f3350a91bf16ef4a8bcaed9fcf71f467a40fb87342a21cdd0f23c241d05635d5df0033a0447a62c33
7
+ data.tar.gz: 94a64062ba15266cf0222e53170f0c187f2c3f39b5f15d7914523dfdcf1a63b77b06356317ea21d748d6c2dec57e7443b2fa36f3c6382d02df9f7c2332f2b301
@@ -16,6 +16,9 @@ Style/PredicateName:
16
16
  Style/AccessorMethodName:
17
17
  Enabled: false
18
18
 
19
+ Style/ClassAndModuleChildren:
20
+ Enabled: false
21
+
19
22
  Metrics/ClassLength:
20
23
  Max: 120
21
24
 
@@ -14,5 +14,14 @@ module ActiveAny
14
14
  def ==(other)
15
15
  other == records
16
16
  end
17
+
18
+ private
19
+
20
+ def exec_queries
21
+ super do |r|
22
+ @association.set_inverse_instance r
23
+ yield r if block_given?
24
+ end
25
+ end
17
26
  end
18
27
  end
@@ -4,10 +4,15 @@ require 'active_any/associations/preloader'
4
4
  require 'active_any/associations/collection_proxy'
5
5
  require 'active_any/associations/association_scope'
6
6
  require 'active_any/associations/builder/association'
7
+ require 'active_any/associations/builder/singular_association'
7
8
  require 'active_any/associations/builder/has_many'
9
+ require 'active_any/associations/builder/has_one'
8
10
  require 'active_any/associations/builder/belongs_to'
9
11
  require 'active_any/associations/association'
12
+ require 'active_any/associations/singular_association'
13
+ require 'active_any/associations/foreign_association'
10
14
  require 'active_any/associations/has_many_association'
15
+ require 'active_any/associations/has_one_association'
11
16
  require 'active_any/associations/belongs_to_association'
12
17
 
13
18
  module ActiveAny
@@ -34,6 +39,11 @@ module ActiveAny
34
39
  reflection = Builder::BelongsTo.build(self, name, scope, options)
35
40
  Reflection.add_reflection self, name, reflection
36
41
  end
42
+
43
+ def has_one(name, scope = nil, options = {})
44
+ reflection = Builder::HasOne.build(self, name, scope, options)
45
+ Reflection.add_reflection self, name, reflection
46
+ end
37
47
  end
38
48
 
39
49
  def initialize_dup(*)
@@ -14,11 +14,7 @@ module ActiveAny
14
14
  end
15
15
 
16
16
  def reader
17
- # TODO: implement
18
- # reload if stale_target?
19
-
20
- @proxy ||= CollectionProxy.create(owner, self)
21
- @proxy.reset_scope
17
+ raise NotImplementedError.new, 'reader is unimplemented'
22
18
  end
23
19
 
24
20
  def writer(_records)
@@ -51,7 +47,7 @@ module ActiveAny
51
47
  def load_target
52
48
  @target = find_target if find_target?
53
49
 
54
- loaded! unless loaded?
50
+ loaded!
55
51
  target
56
52
  # TODO: implement
57
53
  # rescue ActiveRecord::RecordNotFound
@@ -110,7 +106,11 @@ module ActiveAny
110
106
  end
111
107
 
112
108
  def find_target?
113
- !loaded? && klass
109
+ !loaded? && (!owner.new_record? || foreign_key_present?) && klass
110
+ end
111
+
112
+ def foreign_key_present
113
+ false
114
114
  end
115
115
 
116
116
  def inverse_reflection_for(_record)
@@ -2,20 +2,7 @@
2
2
 
3
3
  module ActiveAny
4
4
  module Associations
5
- class BelongsToAssociation < Association
6
- def reader
7
- reload unless loaded?
8
-
9
- target
10
- end
11
-
12
- def writer(_records)
13
- raise NotImplementedError.new, 'writer is unimplemented'
14
- end
15
-
16
- def find_target
17
- scope.first
18
- end
5
+ class BelongsToAssociation < SingularAssociation
19
6
  end
20
7
  end
21
8
  end
@@ -6,19 +6,18 @@ module ActiveAny
6
6
  class Association
7
7
  def self.build(klass, name, scope, options)
8
8
  reflection = create_reflection(klass, name, scope, options)
9
- define_writer_method klass, reflection.name
10
- define_reader_method klass, reflection.name
9
+ define_accessors klass, reflection
11
10
  reflection
12
11
  end
13
12
 
14
13
  VALID_OPTIONS = %i[class_name foreign_key].freeze
15
14
 
16
- def self.valid_options
15
+ def self.valid_options(_options)
17
16
  VALID_OPTIONS
18
17
  end
19
18
 
20
19
  def self.validate_options(options)
21
- options.assert_valid_keys(valid_options)
20
+ options.assert_valid_keys(valid_options(options))
22
21
  end
23
22
 
24
23
  def self.create_reflection(klass, name, scope, options)
@@ -41,16 +40,23 @@ module ActiveAny
41
40
  new_scope
42
41
  end
43
42
 
44
- def self.define_reader_method(klass, name)
45
- klass.class_eval <<-CODE, __FILE__, __LINE__ + 1
43
+ def self.define_accessors(klass, reflection)
44
+ mixin = klass.generated_association_methods
45
+ name = reflection.name
46
+ define_readers(mixin, name)
47
+ define_writers(mixin, name)
48
+ end
49
+
50
+ def self.define_readers(mixin, name)
51
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
46
52
  def #{name}(*args)
47
53
  association(:#{name}).reader(*args)
48
54
  end
49
55
  CODE
50
56
  end
51
57
 
52
- def self.define_writer_method(klass, name)
53
- klass.class_eval <<-CODE, __FILE__, __LINE__ + 1
58
+ def self.define_writers(mixin, name)
59
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
54
60
  def #{name}=(value)
55
61
  association(:#{name}).writer(value)
56
62
  end
@@ -1,17 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActiveAny
4
- module Associations
5
- module Builder
6
- class HasMany < Association
7
- def self.macro
8
- :has_many
9
- end
10
-
11
- def self.valid_options
12
- super + %i[primary_key]
13
- end
14
- end
3
+ module ActiveAny::Associations::Builder
4
+ class HasMany < SingularAssociation
5
+ def self.macro
6
+ :has_many
15
7
  end
16
8
  end
17
9
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny::Associations::Builder
4
+ class HasOne < SingularAssociation
5
+ def self.macro
6
+ :has_one
7
+ end
8
+
9
+ def self.valid_options(options)
10
+ valid = super
11
+ # valid += %i[through source source_type] if options[:through]
12
+ valid
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny::Associations::Builder
4
+ class SingularAssociation < Association
5
+ def self.valid_options(options)
6
+ super + %i[primary_key]
7
+ end
8
+ end
9
+ end
@@ -5,7 +5,7 @@ module ActiveAny
5
5
  class CollectionProxy < ActiveAny::Relation
6
6
  attr_reader :association
7
7
 
8
- delegate :target, :load_target, :load_target,
8
+ delegate :target, :load_target, :load_target, :loaded?, :find, :concat,
9
9
  :size, :empty?, :include?, to: :@association
10
10
 
11
11
  def initialize(klass, association)
@@ -13,6 +13,11 @@ module ActiveAny
13
13
  super(klass)
14
14
  end
15
15
 
16
+ def last(limit = nil)
17
+ load_target if find_from_target?
18
+ super
19
+ end
20
+
16
21
  def take(limit = nil)
17
22
  load_target if find_from_target?
18
23
  super
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny::Associations
4
+ module ForeignAssociation
5
+ def foreign_key_present?
6
+ if reflection.klass.primary_key
7
+ owner.attribute_present?(reflection.record_class_primary_key)
8
+ else
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny::Associations
4
+ module ForeignKeyAssociation
5
+ def foreign_key_present?
6
+ if reflection.klass.primary_key
7
+ owner.attribute_present?(reflection.record_class_primary_key)
8
+ else
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,11 +3,13 @@
3
3
  module ActiveAny
4
4
  module Associations
5
5
  class HasManyAssociation < Association
6
+ include ForeignAssociation
7
+
6
8
  def reader
7
9
  # TODO: implement
8
10
  # reload if stale_target?
9
11
 
10
- @proxy ||= CollectionProxy.create(owner, self)
12
+ @proxy ||= CollectionProxy.create(klass, self)
11
13
  @proxy.reset_scope
12
14
  end
13
15
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Associations
5
+ class HasOneAssociation < SingularAssociation
6
+ include ForeignAssociation
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_any/associations/preloader/association'
4
+ require 'active_any/associations/preloader/singular_association'
4
5
  require 'active_any/associations/preloader/has_many'
6
+ require 'active_any/associations/preloader/has_one'
5
7
  require 'active_any/associations/preloader/belongs_to'
6
8
 
7
9
  module ActiveAny
@@ -3,16 +3,7 @@
3
3
  module ActiveAny
4
4
  module Associations
5
5
  class Preloader
6
- class BelongsTo < Association
7
- def preload(preloader)
8
- associated_records_by_owner(preloader).each do |owner, associated_records|
9
- record = associated_records.first
10
-
11
- association = owner.association(reflection.name)
12
- association.target = record
13
- end
14
- end
15
-
6
+ class BelongsTo < SingularAssociation
16
7
  def association_key_name
17
8
  reflection.options[:primary_key] || klass && klass.primary_key
18
9
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Associations
5
+ class Preloader
6
+ class HasOne < SingularAssociation
7
+ def association_key_name
8
+ reflection.foreign_key
9
+ end
10
+
11
+ def owner_key_name
12
+ reflection.record_class_primary_key
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Associations
5
+ class Preloader
6
+ class SingularAssociation < Association
7
+ def preload(preloader)
8
+ associated_records_by_owner(preloader).each do |owner, associated_records|
9
+ record = associated_records.first
10
+
11
+ association = owner.association(reflection.name)
12
+ association.target = record
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Associations
5
+ class SingularAssociation < Association
6
+ def find_target
7
+ scope.first
8
+ end
9
+
10
+ def reader
11
+ reload unless loaded?
12
+
13
+ target
14
+ end
15
+ end
16
+ end
17
+ end
@@ -16,6 +16,10 @@ module ActiveAny
16
16
  attributes.fetch(name)
17
17
  end
18
18
 
19
+ def attribute_present?(name)
20
+ attributes[name].present?
21
+ end
22
+
19
23
  def attribute_for_inspect(attr_name)
20
24
  value = read_attribute(attr_name)
21
25
 
@@ -37,12 +37,26 @@ module ActiveAny
37
37
  def abstract_class?
38
38
  defined?(@abstract_class) && abstract_class == true
39
39
  end
40
+
41
+ def generated_association_methods
42
+ @generated_association_methods ||= begin
43
+ mod = const_set(:GeneratedAssociationMethods, Module.new)
44
+ private_constant :GeneratedAssociationMethods
45
+ include mod
46
+
47
+ mod
48
+ end
49
+ end
40
50
  end
41
51
 
42
52
  def initialize(*args)
43
53
  init_internals(*args)
44
54
  end
45
55
 
56
+ def new_record?
57
+ false
58
+ end
59
+
46
60
  def [](key)
47
61
  send(key)
48
62
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'active_any/reflection/association_reflection'
4
4
  require 'active_any/reflection/has_many_reflection'
5
+ require 'active_any/reflection/has_one_reflection'
5
6
  require 'active_any/reflection/belongs_to_reflection'
6
7
 
7
8
  module ActiveAny
@@ -33,6 +34,8 @@ module ActiveAny
33
34
  def self.create(macro, name, scope, options, klass)
34
35
  reflection_class =
35
36
  case macro
37
+ when :has_one
38
+ HasOneReflection
36
39
  when :belongs_to
37
40
  BelongsToReflection
38
41
  when :has_many
@@ -40,6 +40,10 @@ module ActiveAny
40
40
  false
41
41
  end
42
42
 
43
+ def has_one?
44
+ false
45
+ end
46
+
43
47
  JoinKeys = Struct.new(:key, :foreign_key)
44
48
 
45
49
  def join_keys
@@ -18,7 +18,7 @@ module ActiveAny
18
18
  private
19
19
 
20
20
  def join_pk
21
- primary_key
21
+ record_class_primary_key
22
22
  end
23
23
 
24
24
  def join_fk
@@ -22,7 +22,7 @@ module ActiveAny
22
22
  end
23
23
 
24
24
  def join_fk
25
- primary_key
25
+ record_class_primary_key
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveAny
4
+ module Reflection
5
+ class HasOneReflection < AssociationReflection
6
+ def association_class
7
+ Associations::HasOneAssociation
8
+ end
9
+
10
+ def macro
11
+ :has_one
12
+ end
13
+
14
+ def has_one?
15
+ true
16
+ end
17
+
18
+ def collection?
19
+ false
20
+ end
21
+
22
+ private
23
+
24
+ def join_pk
25
+ foreign_key
26
+ end
27
+
28
+ def join_fk
29
+ record_class_primary_key
30
+ end
31
+ end
32
+ end
33
+ end
@@ -20,14 +20,6 @@ module ActiveAny
20
20
 
21
21
  class ImmutableRelation < StandardError; end
22
22
 
23
- def self.create(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)
29
- end
30
-
31
23
  def initialize(klass)
32
24
  @klass = klass
33
25
  @records = []
@@ -80,9 +80,23 @@ module ActiveAny
80
80
  end
81
81
  end
82
82
 
83
- def respond_to_missing?(name, include_private)
84
- super
83
+ def respond_to_missing?(name, _)
84
+ super || @klass.respond_to?(name)
85
+ end
86
+ end
87
+
88
+ module ClassMethods
89
+ def create(klass, *args)
90
+ relation_class_for(klass).new(klass, *args)
85
91
  end
92
+
93
+ def relation_class_for(klass)
94
+ klass.relation_delegate_class(self)
95
+ end
96
+ end
97
+
98
+ def respond_to_missing?(name, _)
99
+ super || @klass.respond_to?(name)
86
100
  end
87
101
  end
88
102
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveAny
4
- VERSION = '0.0.7'
4
+ VERSION = '0.0.8'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_any
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - yuemori
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-25 00:00:00.000000000 Z
11
+ date: 2017-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -209,12 +209,20 @@ files:
209
209
  - lib/active_any/associations/builder/association.rb
210
210
  - lib/active_any/associations/builder/belongs_to.rb
211
211
  - lib/active_any/associations/builder/has_many.rb
212
+ - lib/active_any/associations/builder/has_one.rb
213
+ - lib/active_any/associations/builder/singular_association.rb
212
214
  - lib/active_any/associations/collection_proxy.rb
215
+ - lib/active_any/associations/foreign_association.rb
216
+ - lib/active_any/associations/foreign_key_association.rb
213
217
  - lib/active_any/associations/has_many_association.rb
218
+ - lib/active_any/associations/has_one_association.rb
214
219
  - lib/active_any/associations/preloader.rb
215
220
  - lib/active_any/associations/preloader/association.rb
216
221
  - lib/active_any/associations/preloader/belongs_to.rb
217
222
  - lib/active_any/associations/preloader/has_many.rb
223
+ - lib/active_any/associations/preloader/has_one.rb
224
+ - lib/active_any/associations/preloader/singular_association.rb
225
+ - lib/active_any/associations/singular_association.rb
218
226
  - lib/active_any/attribute.rb
219
227
  - lib/active_any/attribute_assignment.rb
220
228
  - lib/active_any/base.rb
@@ -225,6 +233,7 @@ files:
225
233
  - lib/active_any/reflection/association_reflection.rb
226
234
  - lib/active_any/reflection/belongs_to_reflection.rb
227
235
  - lib/active_any/reflection/has_many_reflection.rb
236
+ - lib/active_any/reflection/has_one_reflection.rb
228
237
  - lib/active_any/relation.rb
229
238
  - lib/active_any/relation/delegation.rb
230
239
  - lib/active_any/relation/finder_methods.rb