vorpal 0.0.6 → 0.0.7.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MzY2ZTAwNWJiYmFlY2Y5NGZkZjg4ZTUyMGU4M2U4NjNiNzkxNzdkMg==
5
- data.tar.gz: !binary |-
6
- YTQ0OGZiZGIwOTdmMjcyYmRjZTVmOWRjZGI0ODgzOWRkZTI5OWUxNQ==
2
+ SHA1:
3
+ metadata.gz: ce7c3ca0efe5dbcd1f9aa75bcbf4465a0ffa9c8b
4
+ data.tar.gz: 01a2dad313199961079b71ac522f441d9e68e79b
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZDBiYjBhZDk0ZjY3MjJmMWRjZDcwMWQ3YzAxMGRhYzNiNjkzZjZlMzk5MmIz
10
- ZWVmY2M1YjBiY2NhY2IyZmEyOThkMjA5MGI5YzUzZGJkMTU3Mzg0NWU4NGY5
11
- Zjc3OGVhMmE1ZTExMzg1YWI1MjhlMjU2NjI2MTdjNzQzZGY1MzU=
12
- data.tar.gz: !binary |-
13
- NTNlMTA1NjRiYzc1ODVhNGU5MGNlODIyYTNmOGY0YTQxNTBiMTYzN2UwMzdm
14
- YTk0MTIyNTAxZmNhMzY3MTk5YjEyM2M1ZmIzNTIzMzU2M2FlZWQ2YjM4OGZj
15
- MTU4YjU5ZTlkZmIzZTMzMjAzMWMxNWQ2OGY5YTI5MGZiZTQ3Y2Q=
6
+ metadata.gz: c54780e9bfdaab538b32c2f7a545c1f2182cca2a7ae4f23dce23fb5aeee97947e430961d56d8007c902b7833f38c5057590f4eb78e4613f100d9978602c89f7c
7
+ data.tar.gz: 16db095201901d03d70a7c75120195a529e9b1548ce1bccf059d86f2544a9c495b5ed52d76f9d27f2e3755d8f12c45498bae0107a1c67a030609f812d8c2cef8
data/README.md CHANGED
@@ -74,7 +74,7 @@ end
74
74
 
75
75
  In this aggregate, the Tree is the root and the Branches are inside the aggregate boundary. The Gardener is not technically part of the aggregate but is required for the aggregate to make sense so we say that it is on the aggregate boundary. Only objects that are inside the aggregate boundary will be saved, updated, or destroyed by Vorpal.
76
76
 
77
- POROs must have setters and getters for all fields and associations that are to be persisted. They must also provide a no argument constructor.
77
+ POROs must have setters and getters for all attributes and associations that are to be persisted. They must also provide a no argument constructor.
78
78
 
79
79
  Along with a relational model (in PostgreSQL):
80
80
 
@@ -109,25 +109,17 @@ require 'vorpal'
109
109
  module TreeRepository
110
110
  extend self
111
111
 
112
- class TreeDB < ActiveRecord::Base
113
- self.table_name = 'trees'
114
- end
115
-
116
- class BranchDB < ActiveRecord::Base
117
- self.table_name = 'branches'
118
- end
119
-
120
112
  @repository = Vorpal.define do
121
- map Tree, to: TreeDB do
122
- fields :name
113
+ map Tree do
114
+ attributes :name
123
115
  belongs_to :gardener, owned: false
124
116
  has_many :branches
125
117
  end
126
118
 
127
119
  map Gardener, to: Gardener
128
120
 
129
- map Branch, to: BranchDB do
130
- fields :length, :diameter
121
+ map Branch do
122
+ attributes :length, :diameter
131
123
  belongs_to :tree
132
124
  end
133
125
  end
@@ -183,10 +175,10 @@ It also does not do some things that you might expect from other ORMs:
183
175
  1. No support for validations. Validations are not a persistence concern.
184
176
  1. No AR-style callbacks. Use Infrastructure, Application, or Domain [services](http://martinfowler.com/bliki/EvansClassification.html) instead.
185
177
  1. No has-many-through associations. Use two has-many associations to a join entity instead.
186
- 1. The `id` field is reserved for database primary keys. If you have a natural key/id on your domain model, name it something that makes sense for your domain. It is the strong opinion of the authors that using natural keys as foreign keys is a bad idea. This mixes domain and persistence concerns.
178
+ 1. The `id` attribute is reserved for database primary keys. If you have a natural key/id on your domain model, name it something that makes sense for your domain. It is the strong opinion of the authors that using natural keys as foreign keys is a bad idea. This mixes domain and persistence concerns.
187
179
 
188
180
  ## Constraints
189
- 1. Persisted entities must have getters and setters for all persisted fields and associations. They do not need to be public.
181
+ 1. Persisted entities must have getters and setters for all persisted attributes and associations. They do not need to be public.
190
182
  1. Only supports PostgreSQL.
191
183
 
192
184
  ## Future Enhancements
@@ -196,7 +188,7 @@ It also does not do some things that you might expect from other ORMs:
196
188
  * Value objects.
197
189
  * Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions? TimeZone support?)
198
190
  * More efficient updates (use fewer queries.)
199
- * Nicer DSL for specifying field that have different names in the domain model than in the DB.
191
+ * Nicer DSL for specifying attributes that have different names in the domain model than in the DB.
200
192
 
201
193
  ## FAQ
202
194
 
@@ -216,7 +208,7 @@ For example:
216
208
 
217
209
  ```ruby
218
210
  def find_all
219
- ids = TreeDB.pluck(:id) # use an AR query to determine the aggregate ids
211
+ ids = @repository.db_class(Tree).pluck(:id) # use an AR query to determine the aggregate ids
220
212
  @repository.load_all(ids, Tree) # use the repository to load all the aggregates
221
213
  end
222
214
  ```
@@ -134,6 +134,12 @@ module Vorpal
134
134
  ids
135
135
  end
136
136
 
137
+ # Returns the DB Class (e.g. ActiveRecord::Base class) that is responsible
138
+ # for accessing the associated data in the DB.
139
+ def db_class(domain_class)
140
+ @configs.config_for(domain_class).db_class
141
+ end
142
+
137
143
  private
138
144
 
139
145
  def all_owned_objects(roots)
@@ -2,29 +2,31 @@ require 'simple_serializer/serializer'
2
2
  require 'simple_serializer/deserializer'
3
3
  require 'vorpal/configs'
4
4
  require 'active_support/inflector/methods'
5
+ require 'active_support/core_ext/module/introspection'
5
6
 
6
7
  module Vorpal
7
8
  class ConfigBuilder
8
9
 
9
10
  # @private
10
- def initialize(clazz, options)
11
+ def initialize(clazz, options, db_driver)
11
12
  @domain_class = clazz
12
13
  @class_options = options
14
+ @db_driver = db_driver
13
15
  @has_manys = []
14
16
  @has_ones = []
15
17
  @belongs_tos = []
16
- @fields = []
18
+ @attributes = []
17
19
  end
18
20
 
19
- # Maps the given fields to and from the domain object and the DB. Not needed
21
+ # Maps the given attributes to and from the domain object and the DB. Not needed
20
22
  # if a serializer and deserializer were provided.
21
- def fields(*fields)
22
- @fields = fields
23
+ def attributes(*attributes)
24
+ @attributes.concat(attributes)
23
25
  end
24
26
 
25
27
  # Defines a one-to-many association with a list of objects of the same type.
26
28
  #
27
- # @param name [String] Name of the field that will refer to the other object.
29
+ # @param name [String] Name of the attribute that will refer to the other object.
28
30
  # @param options [Hash]
29
31
  # @option options [Boolean] :owned
30
32
  # @option options [String] :fk
@@ -37,7 +39,7 @@ module Vorpal
37
39
  # Defines a one-to-one association with another object where the foreign key
38
40
  # is stored on the other object.
39
41
  #
40
- # @param name [String] Name of the field that will refer to the other object.
42
+ # @param name [String] Name of the attribute that will refer to the other object.
41
43
  # @param options [Hash]
42
44
  # @option options [Boolean] :owned
43
45
  # @option options [String] :fk
@@ -52,7 +54,7 @@ module Vorpal
52
54
  #
53
55
  # This association can be polymorphic. i.e.
54
56
  #
55
- # @param name [String] Name of the field that will refer to the other object.
57
+ # @param name [String] Name of the attribute that will refer to the other object.
56
58
  # @param options [Hash]
57
59
  # @option options [Boolean] :owned
58
60
  # @option options [String] :fk
@@ -73,25 +75,44 @@ module Vorpal
73
75
  class_config
74
76
  end
75
77
 
78
+ # @private
79
+ def attributes_with_id
80
+ [:id].concat @attributes
81
+ end
82
+
83
+ # @private
84
+ def table_name
85
+ @class_options[:table_name] || ActiveSupport::Inflector.tableize(@domain_class.name)
86
+ end
87
+
88
+ # @private
89
+ def build_db_class
90
+ # Module#parent comes from 'active_support/core_ext/module/introspection'
91
+ parent_module = @domain_class.parent
92
+
93
+ return parent_module.const_get(db_class_name) if parent_module.const_defined?(db_class_name)
94
+
95
+ db_class = @db_driver.build_db_class(table_name)
96
+ parent_module.const_set(db_class_name, db_class)
97
+
98
+ db_class
99
+ end
100
+
76
101
  private
77
102
 
103
+ def db_class_name
104
+ @domain_class.name.split('::').last + 'DB'
105
+ end
106
+
78
107
  def build_class_config
79
108
  Vorpal::ClassConfig.new(
80
109
  domain_class: @domain_class,
81
- db_class: @class_options[:to] || db_class,
82
- serializer: @class_options[:serializer] || serializer(fields_with_id),
83
- deserializer: @class_options[:deserializer] || deserializer(fields_with_id),
110
+ db_class: @class_options[:to] || build_db_class,
111
+ serializer: @class_options[:serializer] || serializer(attributes_with_id),
112
+ deserializer: @class_options[:deserializer] || deserializer(attributes_with_id),
84
113
  )
85
114
  end
86
115
 
87
- def db_class
88
- ActiveSupport::Inflector.constantize("#{@domain_class.name}DB")
89
- end
90
-
91
- def fields_with_id
92
- [:id].concat @fields
93
- end
94
-
95
116
  def build_has_manys
96
117
  @has_manys.map { |options| build_has_many(options) }
97
118
  end
@@ -73,7 +73,7 @@ module Vorpal
73
73
 
74
74
  attr_reader :local_class_config, :remote_class_configs, :fk
75
75
 
76
- # Only one of these two fields needs to be specified
76
+ # Only one of these two attributes needs to be specified
77
77
  # If one is specified, then the association is uni-directional.
78
78
  # If both are specified, then the association is bi-directional.
79
79
  attr_accessor :local_end_config, :remote_end_config
@@ -114,8 +114,8 @@ module Vorpal
114
114
  end
115
115
 
116
116
  def set_foreign_key(local_db_object, remote_object)
117
- local_class_config.set_field(local_db_object, @fk, remote_object.try(:id))
118
- local_class_config.set_field(local_db_object, @fk_type, remote_object.class.name) if polymorphic?
117
+ local_class_config.set_attribute(local_db_object, @fk, remote_object.try(:id))
118
+ local_class_config.set_attribute(local_db_object, @fk_type, remote_object.class.name) if polymorphic?
119
119
  end
120
120
 
121
121
  def foreign_key_info(remote_class_config)
@@ -165,12 +165,12 @@ module Vorpal
165
165
  serialization_required? ? deserializer.deserialize(domain_class.new, attributes) : db_object
166
166
  end
167
167
 
168
- def set_field(db_object, field, value)
169
- db_object.send("#{field}=", value)
168
+ def set_attribute(db_object, attribute, value)
169
+ db_object.send("#{attribute}=", value)
170
170
  end
171
171
 
172
- def get_field(db_object, field)
173
- db_object.send(field)
172
+ def get_attribute(db_object, attribute)
173
+ db_object.send(attribute)
174
174
  end
175
175
 
176
176
  private
@@ -23,11 +23,11 @@ module Vorpal
23
23
  # @param options [Hash] Configure how to map the domain model
24
24
  # @option options [String] :to (Class with the same name as the domain class with a 'DB' appended.)
25
25
  # Class of the ActiveRecord object that will map this domain class to the DB.
26
- # @option options [Object] :serializer (map the {ConfigBuilder#fields} directly)
26
+ # @option options [Object] :serializer (map the {ConfigBuilder#attributes} directly)
27
27
  # Object that will convert the domain objects into a hash.
28
28
  #
29
29
  # Must have a `(Hash) serialize(Object)` method.
30
- # @option options [Object] :deserializer (map the {ConfigBuilder#fields} directly)
30
+ # @option options [Object] :deserializer (map the {ConfigBuilder#attributes} directly)
31
31
  # Object that will set a hash of attribute_names->values onto a new domain
32
32
  # object.
33
33
  #
@@ -38,7 +38,7 @@ module Vorpal
38
38
 
39
39
  # @private
40
40
  def build_class_config(domain_class, options={}, &block)
41
- builder = ConfigBuilder.new(domain_class, options)
41
+ builder = ConfigBuilder.new(domain_class, options, DbDriver.new)
42
42
  builder.instance_exec(&block) if block_given?
43
43
  builder.build
44
44
  end
@@ -51,6 +51,15 @@ module Vorpal
51
51
  result.rows.map(&:first).map(&:to_i)
52
52
  end
53
53
 
54
+ # Builds an ORM Class for accessing data in the given DB table.
55
+ #
56
+ # @return [Class] ActiveRecord::Base Class
57
+ def build_db_class(table_name)
58
+ db_class = Class.new(ActiveRecord::Base)
59
+ db_class.table_name = table_name
60
+ db_class
61
+ end
62
+
54
63
  private
55
64
 
56
65
  def sequence_name(class_config)
@@ -1,3 +1,3 @@
1
1
  module Vorpal
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7.rc1"
3
3
  end
data/lib/vorpal.rb CHANGED
@@ -7,18 +7,18 @@ require "vorpal/configuration"
7
7
  # ```ruby
8
8
  # repository = Vorpal.define do
9
9
  # map Tree do
10
- # fields :name
10
+ # attributes :name
11
11
  # belongs_to :trunk
12
12
  # has_many :branches
13
13
  # end
14
14
  #
15
15
  # map Trunk do
16
- # fields :length
16
+ # attributes :length
17
17
  # has_one :tree
18
18
  # end
19
19
  #
20
20
  # map Branch do
21
- # fields :length
21
+ # attributes :length
22
22
  # belongs_to :tree
23
23
  # end
24
24
  # end
@@ -51,19 +51,10 @@ describe 'Aggregate Repository' do
51
51
 
52
52
  before(:all) do
53
53
  define_table('branches', {length: :decimal, tree_id: :integer, branch_id: :integer}, false)
54
- BranchDB = defineAr('branches')
55
-
56
54
  define_table('bugs', {name: :text, lives_on_id: :integer, lives_on_type: :string}, false)
57
- BugDB = defineAr('bugs')
58
-
59
55
  define_table('fissures', {length: :decimal, tree_id: :integer}, false)
60
-
61
56
  define_table('trees', {name: :text, trunk_id: :integer, environment_id: :integer, environment_type: :string}, false)
62
- TreeDB = defineAr('trees')
63
-
64
57
  define_table('trunks', {length: :decimal}, false)
65
- TrunkDB = defineAr('trunks')
66
-
67
58
  define_table('swamps', {}, false)
68
59
  end
69
60
 
@@ -717,23 +708,23 @@ private
717
708
  def configure_polymorphic_has_many
718
709
  Vorpal.define do
719
710
  map Tree do
720
- fields :name
711
+ attributes :name
721
712
  has_many :branches
722
713
  belongs_to :trunk
723
714
  end
724
715
 
725
716
  map Trunk do
726
- fields :length
717
+ attributes :length
727
718
  has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
728
719
  end
729
720
 
730
721
  map Branch do
731
- fields :length
722
+ attributes :length
732
723
  has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
733
724
  end
734
725
 
735
726
  map Bug do
736
- fields :name
727
+ attributes :name
737
728
  end
738
729
  end
739
730
  end
@@ -741,16 +732,16 @@ private
741
732
  def configure_polymorphic_belongs_to
742
733
  Vorpal.define do
743
734
  map Bug do
744
- fields :name
735
+ attributes :name
745
736
  belongs_to :lives_on, fk: :lives_on_id, fk_type: :lives_on_type, child_classes: [Trunk, Branch]
746
737
  end
747
738
 
748
739
  map Trunk do
749
- fields :length
740
+ attributes :length
750
741
  end
751
742
 
752
743
  map Branch do
753
- fields :length
744
+ attributes :length
754
745
  end
755
746
  end
756
747
  end
@@ -758,7 +749,7 @@ private
758
749
  def configure_ar_polymorphic_belongs_to
759
750
  Vorpal.define do
760
751
  map Tree do
761
- fields :name
752
+ attributes :name
762
753
  belongs_to :environment, owned: false, fk: :environment_id, fk_type: :environment_type, child_class: Swamp
763
754
  end
764
755
 
@@ -769,16 +760,16 @@ private
769
760
  def configure_unowned_polymorphic_belongs_to
770
761
  Vorpal.define do
771
762
  map Bug do
772
- fields :name
763
+ attributes :name
773
764
  belongs_to :lives_on, owned: false, fk: :lives_on_id, fk_type: :lives_on_type, child_classes: [Trunk, Branch]
774
765
  end
775
766
 
776
767
  map Trunk do
777
- fields :length
768
+ attributes :length
778
769
  end
779
770
 
780
771
  map Branch do
781
- fields :length
772
+ attributes :length
782
773
  end
783
774
  end
784
775
  end
@@ -786,17 +777,17 @@ private
786
777
  def configure_unowned
787
778
  Vorpal.define do
788
779
  map Tree do
789
- fields :name
780
+ attributes :name
790
781
  has_many :branches, owned: false
791
782
  belongs_to :trunk, owned: false
792
783
  end
793
784
 
794
785
  map Trunk do
795
- fields :length
786
+ attributes :length
796
787
  end
797
788
 
798
789
  map Branch do
799
- fields :length
790
+ attributes :length
800
791
  end
801
792
  end
802
793
  end
@@ -804,12 +795,12 @@ private
804
795
  def configure_recursive
805
796
  Vorpal.define do
806
797
  map Branch do
807
- fields :length
798
+ attributes :length
808
799
  has_many :branches
809
800
  end
810
801
 
811
802
  map Tree do
812
- fields :name
803
+ attributes :name
813
804
  has_many :branches
814
805
  end
815
806
  end
@@ -818,12 +809,12 @@ private
818
809
  def configure_with_cycle
819
810
  Vorpal.define do
820
811
  map Branch do
821
- fields :length
812
+ attributes :length
822
813
  belongs_to :tree
823
814
  end
824
815
 
825
816
  map Tree do
826
- fields :name
817
+ attributes :name
827
818
  has_many :branches
828
819
  end
829
820
  end
@@ -832,18 +823,18 @@ private
832
823
  def configure(options={})
833
824
  Vorpal.define(options) do
834
825
  map Tree do
835
- fields :name
826
+ attributes :name
836
827
  belongs_to :trunk
837
828
  has_many :fissures
838
829
  has_many :branches
839
830
  end
840
831
 
841
832
  map Trunk do
842
- fields :length
833
+ attributes :length
843
834
  end
844
835
 
845
836
  map Branch do
846
- fields :length
837
+ attributes :length
847
838
  end
848
839
 
849
840
  map Fissure, to: Fissure
@@ -853,12 +844,12 @@ private
853
844
  def configure_has_one
854
845
  Vorpal.define do
855
846
  map Trunk do
856
- fields :length
847
+ attributes :length
857
848
  has_one :tree
858
849
  end
859
850
 
860
851
  map Tree do
861
- fields :name
852
+ attributes :name
862
853
  end
863
854
  end
864
855
  end
@@ -866,12 +857,12 @@ private
866
857
  def configure_unowned_has_one
867
858
  Vorpal.define do
868
859
  map Trunk do
869
- fields :length
860
+ attributes :length
870
861
  has_one :tree, owned: false
871
862
  end
872
863
 
873
864
  map Tree do
874
- fields :name
865
+ attributes :name
875
866
  end
876
867
  end
877
868
  end
@@ -165,26 +165,26 @@ describe 'performance' do
165
165
  def build_repository
166
166
  Vorpal.define do
167
167
  map Tree do
168
- fields :name
168
+ attributes :name
169
169
  belongs_to :trunk
170
170
  has_many :branches
171
171
  end
172
172
 
173
173
  map Trunk do
174
- fields :length
174
+ attributes :length
175
175
  has_one :tree
176
176
  has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
177
177
  end
178
178
 
179
179
  map Branch do
180
- fields :length
180
+ attributes :length
181
181
  belongs_to :tree
182
182
  has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
183
183
  has_many :branches
184
184
  end
185
185
 
186
186
  map Bug do
187
- fields :name
187
+ attributes :name
188
188
  belongs_to :lives_on, fk: :lives_on_id, fk_type: :lives_on_type, child_classes: [Trunk, Branch]
189
189
  end
190
190
  end
@@ -0,0 +1,67 @@
1
+ require 'unit_spec_helper'
2
+
3
+ require 'vorpal/config_builder'
4
+
5
+ describe Vorpal::ConfigBuilder do
6
+ class Tester; end
7
+
8
+ let(:builder) { Vorpal::ConfigBuilder.new(Tester, {}, nil) }
9
+
10
+ describe 'mapping attributes' do
11
+ it 'allows the \'attributes\' method to be called multiple times' do
12
+ builder.attributes :first
13
+ builder.attributes :second
14
+
15
+ expect(builder.attributes_with_id).to eq([:id, :first, :second])
16
+ end
17
+ end
18
+
19
+ describe 'table name' do
20
+ it 'is derived from the domain class name' do
21
+ builder = Vorpal::ConfigBuilder.new(A::B::C::Test, {}, nil)
22
+ expect(builder.table_name).to eq('a/b/c/tests')
23
+ end
24
+
25
+ it 'can be manually specified' do
26
+ builder = Vorpal::ConfigBuilder.new(Tester, {table_name: 'testing123'}, nil)
27
+ expect(builder.table_name).to eq('testing123')
28
+ end
29
+ end
30
+
31
+ describe 'build_db_class' do
32
+ it 'sets the class name' do
33
+ driver = instance_double(Vorpal::DbDriver)
34
+ new_class = Class.new
35
+ expect(driver).to receive(:build_db_class).and_return(new_class)
36
+
37
+ builder = Vorpal::ConfigBuilder.new(A::B::C::Test, {}, driver)
38
+
39
+ builder.build_db_class
40
+
41
+ expect(A::B::C::TestDB).to eq(new_class)
42
+ end
43
+
44
+ it 'does not redefine constants' do
45
+ stub_const('A::B::C::TestDB', 1)
46
+
47
+ builder = Vorpal::ConfigBuilder.new(A::B::C::Test, {}, nil)
48
+
49
+ db_class = builder.build_db_class
50
+
51
+ expect(A::B::C::TestDB).to eq(1)
52
+ expect(db_class).to eq(1)
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ module A
59
+ module B
60
+ module C
61
+ class Test
62
+
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,103 @@
1
+ require 'unit_spec_helper'
2
+ require 'vorpal'
3
+ require 'virtus'
4
+
5
+ describe Vorpal::DbLoader do
6
+
7
+ class Post; end
8
+
9
+ class Comment
10
+ include Virtus.model
11
+
12
+ attribute :id, Integer
13
+ attribute :post, Post
14
+ end
15
+
16
+ class Post
17
+ include Virtus.model
18
+
19
+ attribute :id, Integer
20
+ attribute :best_comment, Comment
21
+ attribute :comments, Array[Comment]
22
+ end
23
+
24
+ class PostDB
25
+ include Virtus.model
26
+ attribute :id, Integer
27
+ attribute :best_comment_id, Integer
28
+ end
29
+
30
+ class CommentDB
31
+ include Virtus.model
32
+ attribute :id, Integer
33
+ attribute :post_id, Integer
34
+ end
35
+
36
+ before(:all) do
37
+ # define_table('comments', {post_id: :integer}, false)
38
+ # CommentDB = defineAr('comments')
39
+
40
+ # define_table('posts', {best_comment_id: :integer}, false)
41
+ # PostDB = defineAr('posts')
42
+ end
43
+
44
+ # it 'loads an object once even when referred to by different associations of different types2' do
45
+ # post_config = Vorpal.build_class_config(Post) do
46
+ # attributes :name
47
+ # belongs_to :best_comment, child_class: Comment
48
+ # has_many :comments
49
+ # end
50
+ #
51
+ # comment_config = Vorpal.build_class_config(Comment) do
52
+ # attributes :length
53
+ # end
54
+ #
55
+ # master_config = Vorpal::MasterConfig.new([post_config, comment_config])
56
+ #
57
+ # driver = Vorpal::DbDriver.new
58
+ #
59
+ # best_comment_db = CommentDB.create!
60
+ # post_db = PostDB.create!(best_comment_id: best_comment_db.id)
61
+ # best_comment_db.update_attributes!(post_id: post_db.id)
62
+ #
63
+ # loader = Vorpal::DbLoader.new(false, driver)
64
+ # loaded_objects = loader.load_from_db([post_db.id], master_config.config_for(Post))
65
+ # p loaded_objects.all_objects
66
+ # # expect(loaded_objects.all_objects.size).to eq(2)
67
+ #
68
+ # repo = Vorpal::AggregateRepository.new(driver, master_config)
69
+ # post = repo.load(post_db.id, Post)
70
+ # p post
71
+ # expect(post.comments.size).to eq(1)
72
+ # end
73
+
74
+ it 'loads an object once even when referred to by different associations of different types with stubs' do
75
+ post_config = Vorpal.build_class_config(Post, to: PostDB) do
76
+ attributes :name
77
+ belongs_to :best_comment, child_class: Comment
78
+ has_many :comments
79
+ end
80
+
81
+ comment_config = Vorpal.build_class_config(Comment, to: CommentDB) do
82
+ attributes :length
83
+ end
84
+
85
+ Vorpal::MasterConfig.new([post_config, comment_config])
86
+
87
+ best_comment_db = CommentDB.new
88
+ best_comment_db.id = 99
89
+ post_db = PostDB.new(best_comment_id: best_comment_db.id)
90
+ post_db.id = 100
91
+ best_comment_db.post_id = post_db.id
92
+
93
+ driver = instance_double("Vorpal::DbDriver")
94
+ expect(driver).to receive(:load_by_id).with(post_config, [post_db.id]).and_return([post_db])
95
+ expect(driver).to receive(:load_by_id).with(comment_config, [best_comment_db.id]).and_return([best_comment_db])
96
+ expect(driver).to receive(:load_by_foreign_key).and_return([best_comment_db])
97
+
98
+ loader = Vorpal::DbLoader.new(false, driver)
99
+ loaded_objects = loader.load_from_db([post_db.id], post_config)
100
+
101
+ expect(loaded_objects.all_objects).to contain_exactly(post_db, best_comment_db)
102
+ end
103
+ end
metadata CHANGED
@@ -1,139 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vorpal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Kirby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-08 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simple_serializer
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: equalizer
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '10.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: 3.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: activerecord
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: 3.2.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.2.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: 0.17.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.17.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: virtus
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ~>
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
117
  version: '1.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ~>
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: activerecord-import
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ~>
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: 0.3.1
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ~>
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.3.1
139
139
  description: An ORM framelet that fits on top of ActiveRecord to give you 'Data Mapper'
@@ -144,8 +144,8 @@ executables: []
144
144
  extensions: []
145
145
  extra_rdoc_files: []
146
146
  files:
147
- - .gitignore
148
- - .yardopts
147
+ - ".gitignore"
148
+ - ".yardopts"
149
149
  - Gemfile
150
150
  - LICENSE.txt
151
151
  - README.md
@@ -168,9 +168,10 @@ files:
168
168
  - spec/integration_spec_helper.rb
169
169
  - spec/unit_spec_helper.rb
170
170
  - spec/vorpal/acceptance/aggregate_repository_spec.rb
171
- - spec/vorpal/acceptance/performance_spec.rb
172
- - spec/vorpal/unit/class_config_builder_spec.rb
171
+ - spec/vorpal/performance/performance_spec.rb
172
+ - spec/vorpal/unit/config_builder_spec.rb
173
173
  - spec/vorpal/unit/configs_spec.rb
174
+ - spec/vorpal/unit/db_loader_spec.rb
174
175
  - spec/vorpal/unit/identity_map_spec.rb
175
176
  - spec/vorpal/unit/loaded_objects_spec.rb
176
177
  - vorpal.gemspec
@@ -184,17 +185,17 @@ require_paths:
184
185
  - lib
185
186
  required_ruby_version: !ruby/object:Gem::Requirement
186
187
  requirements:
187
- - - ! '>='
188
+ - - ">="
188
189
  - !ruby/object:Gem::Version
189
190
  version: '0'
190
191
  required_rubygems_version: !ruby/object:Gem::Requirement
191
192
  requirements:
192
- - - ! '>='
193
+ - - ">"
193
194
  - !ruby/object:Gem::Version
194
- version: '0'
195
+ version: 1.3.1
195
196
  requirements: []
196
197
  rubyforge_project:
197
- rubygems_version: 2.4.5
198
+ rubygems_version: 2.4.8
198
199
  signing_key:
199
200
  specification_version: 4
200
201
  summary: Separate your domain model from your persistence mechanism.
@@ -203,8 +204,9 @@ test_files:
203
204
  - spec/integration_spec_helper.rb
204
205
  - spec/unit_spec_helper.rb
205
206
  - spec/vorpal/acceptance/aggregate_repository_spec.rb
206
- - spec/vorpal/acceptance/performance_spec.rb
207
- - spec/vorpal/unit/class_config_builder_spec.rb
207
+ - spec/vorpal/performance/performance_spec.rb
208
+ - spec/vorpal/unit/config_builder_spec.rb
208
209
  - spec/vorpal/unit/configs_spec.rb
210
+ - spec/vorpal/unit/db_loader_spec.rb
209
211
  - spec/vorpal/unit/identity_map_spec.rb
210
212
  - spec/vorpal/unit/loaded_objects_spec.rb
@@ -1,13 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- require 'vorpal/config_builder'
4
-
5
- describe Vorpal::ConfigBuilder do
6
- class Tester; end
7
-
8
- it 'includes the primary key in the list of fields' do
9
- # builder = Vorpal::ConfigBuilder.new(Tester, {})
10
- # config = builder.build
11
- # config.field
12
- end
13
- end