lotus-model 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +6 -0
  4. data/.yardopts +5 -0
  5. data/EXAMPLE.md +217 -0
  6. data/Gemfile +14 -2
  7. data/README.md +303 -3
  8. data/Rakefile +17 -1
  9. data/lib/lotus-model.rb +1 -0
  10. data/lib/lotus/entity.rb +157 -0
  11. data/lib/lotus/model.rb +23 -2
  12. data/lib/lotus/model/adapters/abstract.rb +167 -0
  13. data/lib/lotus/model/adapters/implementation.rb +111 -0
  14. data/lib/lotus/model/adapters/memory/collection.rb +132 -0
  15. data/lib/lotus/model/adapters/memory/command.rb +90 -0
  16. data/lib/lotus/model/adapters/memory/query.rb +457 -0
  17. data/lib/lotus/model/adapters/memory_adapter.rb +149 -0
  18. data/lib/lotus/model/adapters/sql/collection.rb +209 -0
  19. data/lib/lotus/model/adapters/sql/command.rb +67 -0
  20. data/lib/lotus/model/adapters/sql/query.rb +615 -0
  21. data/lib/lotus/model/adapters/sql_adapter.rb +154 -0
  22. data/lib/lotus/model/mapper.rb +101 -0
  23. data/lib/lotus/model/mapping.rb +23 -0
  24. data/lib/lotus/model/mapping/coercer.rb +80 -0
  25. data/lib/lotus/model/mapping/collection.rb +336 -0
  26. data/lib/lotus/model/version.rb +4 -1
  27. data/lib/lotus/repository.rb +620 -0
  28. data/lotus-model.gemspec +15 -11
  29. data/test/entity_test.rb +126 -0
  30. data/test/fixtures.rb +81 -0
  31. data/test/model/adapters/abstract_test.rb +75 -0
  32. data/test/model/adapters/implementation_test.rb +22 -0
  33. data/test/model/adapters/memory/query_test.rb +91 -0
  34. data/test/model/adapters/memory_adapter_test.rb +1044 -0
  35. data/test/model/adapters/sql/query_test.rb +121 -0
  36. data/test/model/adapters/sql_adapter_test.rb +1078 -0
  37. data/test/model/mapper_test.rb +94 -0
  38. data/test/model/mapping/coercer_test.rb +27 -0
  39. data/test/model/mapping/collection_test.rb +82 -0
  40. data/test/repository_test.rb +283 -0
  41. data/test/test_helper.rb +30 -0
  42. data/test/version_test.rb +7 -0
  43. metadata +109 -11
@@ -0,0 +1,154 @@
1
+ require 'lotus/model/adapters/abstract'
2
+ require 'lotus/model/adapters/implementation'
3
+ require 'lotus/model/adapters/sql/collection'
4
+ require 'lotus/model/adapters/sql/command'
5
+ require 'lotus/model/adapters/sql/query'
6
+ require 'sequel'
7
+
8
+ module Lotus
9
+ module Model
10
+ module Adapters
11
+ # Adapter for SQL databases
12
+ #
13
+ # In order to use it with a specific database, you must require the Ruby
14
+ # gem before of loading Lotus::Model.
15
+ #
16
+ # @see Lotus::Model::Adapters::Implementation
17
+ #
18
+ # @api private
19
+ # @since 0.1.0
20
+ class SqlAdapter < Abstract
21
+ include Implementation
22
+
23
+ # Initialize the adapter.
24
+ #
25
+ # Lotus::Model uses Sequel. For a complete reference of the connection
26
+ # URI, please see: http://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html
27
+ #
28
+ # @param mapper [Object] the database mapper
29
+ # @param uri [String] the connection uri for the database
30
+ #
31
+ # @return [Lotus::Model::Adapters::SqlAdapter]
32
+ #
33
+ # @raise [Lotus::Model::Adapters::DatabaseAdapterNotFound] if the given
34
+ # URI refers to an unknown or not registered adapter.
35
+ #
36
+ # @raise [URI::InvalidURIError] if the given URI is malformed
37
+ #
38
+ # @see Lotus::Model::Mapper
39
+ # @see http://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html
40
+ #
41
+ # @api private
42
+ # @since 0.1.0
43
+ def initialize(mapper, uri)
44
+ super
45
+ @connection = Sequel.connect(@uri)
46
+ rescue Sequel::AdapterNotFound => e
47
+ raise DatabaseAdapterNotFound.new(e.message)
48
+ end
49
+
50
+ # Creates a record in the database for the given entity.
51
+ # It assigns the `id` attribute, in case of success.
52
+ #
53
+ # @param collection [Symbol] the target collection (it must be mapped).
54
+ # @param entity [#id=] the entity to create
55
+ #
56
+ # @return [Object] the entity
57
+ #
58
+ # @api private
59
+ # @since 0.1.0
60
+ def create(collection, entity)
61
+ entity.id = command(
62
+ query(collection)
63
+ ).create(entity)
64
+ entity
65
+ end
66
+
67
+ # Updates a record in the database corresponding to the given entity.
68
+ #
69
+ # @param collection [Symbol] the target collection (it must be mapped).
70
+ # @param entity [#id] the entity to update
71
+ #
72
+ # @return [Object] the entity
73
+ #
74
+ # @api private
75
+ # @since 0.1.0
76
+ def update(collection, entity)
77
+ command(
78
+ _find(collection, entity.id)
79
+ ).update(entity)
80
+ end
81
+
82
+ # Deletes a record in the database corresponding to the given entity.
83
+ #
84
+ # @param collection [Symbol] the target collection (it must be mapped).
85
+ # @param entity [#id] the entity to delete
86
+ #
87
+ # @api private
88
+ # @since 0.1.0
89
+ def delete(collection, entity)
90
+ command(
91
+ _find(collection, entity.id)
92
+ ).delete
93
+ end
94
+
95
+ # Deletes all the records from the given collection.
96
+ #
97
+ # @param collection [Symbol] the target collection (it must be mapped).
98
+ #
99
+ # @api private
100
+ # @since 0.1.0
101
+ def clear(collection)
102
+ command(query(collection)).clear
103
+ end
104
+
105
+ # Fabricates a command for the given query.
106
+ #
107
+ # @param query [Lotus::Model::Adapters::Sql::Query] the query object to
108
+ # act on.
109
+ #
110
+ # @return [Lotus::Model::Adapters::Sql::Command]
111
+ #
112
+ # @see Lotus::Model::Adapters::Sql::Command
113
+ #
114
+ # @api private
115
+ # @since 0.1.0
116
+ def command(query)
117
+ Sql::Command.new(query)
118
+ end
119
+
120
+ # Fabricates a query
121
+ #
122
+ # @param collection [Symbol] the target collection (it must be mapped).
123
+ # @param blk [Proc] a block of code to be executed in the context of
124
+ # the query.
125
+ #
126
+ # @return [Lotus::Model::Adapters::Sql::Query]
127
+ #
128
+ # @see Lotus::Model::Adapters::Sql::Query
129
+ #
130
+ # @api private
131
+ # @since 0.1.0
132
+ def query(collection, context = nil, &blk)
133
+ Sql::Query.new(_collection(collection), context, &blk)
134
+ end
135
+
136
+ private
137
+
138
+ # Returns a collection from the given name.
139
+ #
140
+ # @param name [Symbol] a name of the collection (it must be mapped).
141
+ #
142
+ # @return [Lotus::Model::Adapters::Sql::Collection]
143
+ #
144
+ # @see Lotus::Model::Adapters::Sql::Collection
145
+ #
146
+ # @api private
147
+ # @since 0.1.0
148
+ def _collection(name)
149
+ Sql::Collection.new(@connection[name], _mapped_collection(name))
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,101 @@
1
+ require 'lotus/model/mapping'
2
+
3
+ module Lotus
4
+ module Model
5
+ # A persistence mapper that keep entities independent from database details.
6
+ #
7
+ # This is database independent. It can work with SQL, document, and even
8
+ # with key/value stores.
9
+ #
10
+ # @since 0.1.0
11
+ #
12
+ # @see http://martinfowler.com/eaaCatalog/dataMapper.html
13
+ #
14
+ # @example
15
+ # require 'lotus/model'
16
+ #
17
+ # mapper = Lotus::Model::Mapper.new do
18
+ # collection :users do
19
+ # entity User
20
+ #
21
+ # attribute :id, Integer
22
+ # attribute :name, String
23
+ # end
24
+ # end
25
+ #
26
+ # # This guarantees thread-safety and should happen as last thing before
27
+ # # to start the app code.
28
+ # mapper.load!
29
+ class Mapper
30
+ # @attr_reader collections [Hash] all the mapped collections
31
+ #
32
+ # @since 0.1.0
33
+ # @api private
34
+ attr_reader :collections
35
+
36
+ # Instantiate a mapper.
37
+ #
38
+ # It accepts an optional argument (`coercer`) a class that defines the
39
+ # policies for entities translations from/to the database.
40
+ #
41
+ # If provided, this class must implement the following interface:
42
+ #
43
+ # * #initialize(collection) # Lotus::Model::Mapping::Collection
44
+ # * #to_record(entity) # translates an entity to the database type
45
+ # * #from_record(record) # translates a record into an entity
46
+ # * #deserialize_*(value) # a set of methods, one for each database column.
47
+ #
48
+ # If not given, it uses `Lotus::Model::Mapping::Coercer`, by default.
49
+ #
50
+ #
51
+ #
52
+ # @param coercer [Class] an optional class that defines the policies for
53
+ # entity translations from/to the database.
54
+ #
55
+ # @param blk [Proc] an optional block of code that gets evaluated in the
56
+ # context of the current instance
57
+ #
58
+ # @return [Lotus::Model::Mapper]
59
+ #
60
+ # @since 0.1.0
61
+ def initialize(coercer = nil, &blk)
62
+ @coercer = coercer || Mapping::Coercer
63
+ @collections = {}
64
+ instance_eval(&blk) if block_given?
65
+ end
66
+
67
+ # Maps a collection.
68
+ #
69
+ # A collection is a set of homogeneous records. Think of a table of a SQL
70
+ # database or about collection of MongoDB.
71
+ #
72
+ # @param name [Symbol] the name of the mapped collection. If used with a
73
+ # SQL database it's the table name.
74
+ #
75
+ # @param blk [Proc] the block that maps the attributes of that collection.
76
+ #
77
+ # @since 0.1.0
78
+ #
79
+ # @see Lotus::Model::Mapping::Collection
80
+ def collection(name, &blk)
81
+ if block_given?
82
+ @collections[name] = Mapping::Collection.new(name, @coercer, &blk)
83
+ else
84
+ # TODO implement a getter with a private API.
85
+ @collections[name] or raise Mapping::UnmappedCollectionError.new(name)
86
+ end
87
+ end
88
+
89
+ # Loads the internals of the mapper, in order to guarantee thread safety.
90
+ #
91
+ # This method MUST be invoked as the last thing before of start using the
92
+ # application.
93
+ #
94
+ # @since 0.1.0
95
+ def load!
96
+ @collections.each {|_, collection| collection.load! }
97
+ self
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,23 @@
1
+ require 'lotus/model/mapping/collection'
2
+ require 'lotus/model/mapping/coercer'
3
+
4
+ module Lotus
5
+ module Model
6
+ # Mapping internal utilities
7
+ #
8
+ # @since 0.1.0
9
+ module Mapping
10
+ # Unmapped collection error.
11
+ #
12
+ # It gets raised when the application tries to access to a non-mapped
13
+ # collection.
14
+ #
15
+ # @since 0.1.0
16
+ class UnmappedCollectionError < ::StandardError
17
+ def initialize(name)
18
+ super("Cannot find collection: #{ name }")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,80 @@
1
+ require 'lotus/utils/kernel'
2
+
3
+ module Lotus
4
+ module Model
5
+ module Mapping
6
+ # Translates values from/to the database with the corresponding Ruby type.
7
+ #
8
+ # @api private
9
+ # @since 0.1.0
10
+ class Coercer
11
+ # Initialize a coercer for the given collection.
12
+ #
13
+ # @param collection [Lotus::Model::Mapping::Collection] the collection
14
+ #
15
+ # @api private
16
+ # @since 0.1.0
17
+ def initialize(collection)
18
+ @collection = collection
19
+ _compile!
20
+ end
21
+
22
+ # Translates the given entity into a format compatible with the database.
23
+ #
24
+ # @param entity [Object] the entity
25
+ #
26
+ # @return [Hash]
27
+ #
28
+ # @api private
29
+ # @since 0.1.0
30
+ def to_record(entity)
31
+ end
32
+
33
+ # Translates the given record into a Ruby object.
34
+ #
35
+ # @param record [Hash]
36
+ #
37
+ # @return [Object]
38
+ #
39
+ # @api private
40
+ # @since 0.1.0
41
+ def from_record(record)
42
+ end
43
+
44
+ private
45
+ # Compile itself for perfomance boost.
46
+ #
47
+ # @api private
48
+ # @since 0.1.0
49
+ def _compile!
50
+ code = @collection.attributes.map do |_,(klass,mapped)|
51
+ %{
52
+ def deserialize_#{ mapped }(value)
53
+ Lotus::Utils::Kernel.#{klass}(value)
54
+ end
55
+ }
56
+ end.join("\n")
57
+
58
+ instance_eval %{
59
+ def to_record(entity)
60
+ if entity.id
61
+ Hash[*[#{ @collection.attributes.map{|name,(_,mapped)| ":#{mapped},entity.#{name}"}.join(',') }]]
62
+ else
63
+ Hash[*[#{ @collection.attributes.reject{|name,_| name == @collection.identity }.map{|name,(_,mapped)| ":#{mapped},entity.#{name}"}.join(',') }]]
64
+ end
65
+ end
66
+
67
+ def from_record(record)
68
+ #{ @collection.entity }.new(
69
+ Hash[*[#{ @collection.attributes.map{|name,(klass,mapped)| ":#{name},Lotus::Utils::Kernel.#{klass}(record[:#{mapped}])"}.join(',') }]]
70
+ )
71
+ end
72
+
73
+ #{ code }
74
+ }
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
@@ -0,0 +1,336 @@
1
+ module Lotus
2
+ module Model
3
+ module Mapping
4
+ # Maps a collection and its attributes.
5
+ #
6
+ # A collection is a set of homogeneous records. Think of a table of a SQL
7
+ # database or about collection of MongoDB.
8
+ #
9
+ # This is database independent. It can work with SQL, document, and even
10
+ # with key/value stores.
11
+ #
12
+ # @since 0.1.0
13
+ #
14
+ # @see Lotus::Model::Mapper
15
+ #
16
+ # @example
17
+ # require 'lotus/model'
18
+ #
19
+ # mapper = Lotus::Model::Mapper.new do
20
+ # collection :users do
21
+ # entity User
22
+ #
23
+ # attribute :id, Integer
24
+ # attribute :name, String
25
+ # end
26
+ # end
27
+ class Collection
28
+ # Repository name suffix
29
+ #
30
+ # @api private
31
+ # @since 0.1.0
32
+ #
33
+ # @see Lotus::Repository
34
+ REPOSITORY_SUFFIX = 'Repository'.freeze
35
+
36
+ # Defines top level constant for attribute usage.
37
+ #
38
+ # @since 0.1.0
39
+ #
40
+ # @see Lotus::Model::Mapping::Collection#attribute
41
+ #
42
+ # @example
43
+ # require 'lotus/model'
44
+ #
45
+ # mapper = Lotus::Model::Mapper.new do
46
+ # collection :articles do
47
+ # entity Article
48
+ #
49
+ # attribute :published, Boolean
50
+ # end
51
+ # end
52
+ class ::Boolean
53
+ end
54
+
55
+ # @attr_reader name [Symbol] the name of the collection
56
+ #
57
+ # @since 0.1.0
58
+ # @api private
59
+ attr_reader :name
60
+
61
+ # @attr_reader coercer_class [Class] the coercer class
62
+ #
63
+ # @since 0.1.0
64
+ # @api private
65
+ attr_reader :coercer_class
66
+
67
+ # @attr_reader attributes [Hash] the set of attributes
68
+ #
69
+ # @since 0.1.0
70
+ # @api private
71
+ attr_reader :attributes
72
+
73
+ # Instantiate a new collection
74
+ #
75
+ # @param name [Symbol] the name of the mapped collection. If used with a
76
+ # SQL database it's the table name.
77
+ #
78
+ # @param blk [Proc] the block that maps the attributes of that collection.
79
+ #
80
+ # @since 0.1.0
81
+ #
82
+ # @see Lotus::Model::Mapper#collection
83
+ def initialize(name, coercer_class, &blk)
84
+ @name, @coercer_class, @attributes = name, coercer_class, {}
85
+ instance_eval(&blk) if block_given?
86
+ end
87
+
88
+ # Defines the entity that is persisted with this collection.
89
+ #
90
+ # The entity can be any kind of object as long it implements the
91
+ # following interface: `#initialize(attributes = {})`.
92
+ #
93
+ # @param klass [Class] the entity persisted with this collection.
94
+ #
95
+ # @since 0.1.0
96
+ #
97
+ # @see Lotus::Entity
98
+ def entity(klass = nil)
99
+ if klass
100
+ @entity = klass
101
+ else
102
+ @entity
103
+ end
104
+ end
105
+
106
+ # Defines the identity for a collection.
107
+ #
108
+ # An identity is an unique value that identifies a record.
109
+ # If used with an SQL table it corresponds to the primary key.
110
+ #
111
+ # This is an optional feature.
112
+ # By default the system assumes that your identity is `:id`.
113
+ # If this is the case, you can omit the value, otherwise you have to
114
+ # specify it.
115
+ #
116
+ # @param name [Symbol] the name of the identity
117
+ #
118
+ # @since 0.1.0
119
+ #
120
+ # @example Default
121
+ # require 'lotus/model'
122
+ #
123
+ # # We have an SQL table `users` with a primary key `id`.
124
+ # #
125
+ # # This this is compliant to the mapper default, we can omit
126
+ # # `#identity`.
127
+ #
128
+ # mapper = Lotus::Model::Mapper.new do
129
+ # collection :users do
130
+ # entity User
131
+ #
132
+ # # attribute definitions..
133
+ # end
134
+ # end
135
+ #
136
+ # @example Custom identity
137
+ # require 'lotus/model'
138
+ #
139
+ # # We have an SQL table `articles` with a primary key `i_id`.
140
+ # #
141
+ # # This schema diverges from the expected default: `id`, that's why
142
+ # # we need to use #identity to let the mapper to recognize the
143
+ # # primary key.
144
+ #
145
+ # mapper = Lotus::Model::Mapper.new do
146
+ # collection :articles do
147
+ # entity Article
148
+ #
149
+ # # attribute definitions..
150
+ #
151
+ # identity :i_id
152
+ # end
153
+ # end
154
+ def identity(name = nil)
155
+ if name
156
+ @identity = name
157
+ else
158
+ @identity || :id
159
+ end
160
+ end
161
+
162
+ # Map an attribute.
163
+ #
164
+ # An attribute defines a property of an object.
165
+ # This is storage independent. For instance, it can map an SQL column,
166
+ # a MongoDB attribute or everything that makes sense for your database.
167
+ #
168
+ # Each attribute defines an Ruby type, to coerce that value from the
169
+ # database. This fixes a huge problem, because database types don't
170
+ # match Ruby types.
171
+ # Think of Redis, where everything is stored as a string or integer,
172
+ # the mapper translates values from/to the database.
173
+ #
174
+ # It supports the following types:
175
+ #
176
+ # * Array
177
+ # * Boolean
178
+ # * Date
179
+ # * DateTime
180
+ # * Float
181
+ # * Hash
182
+ # * Integer
183
+ # * Set
184
+ # * String
185
+ # * Time
186
+ #
187
+ # @param name [Symbol] the name of the attribute, as we want it to be
188
+ # mapped in the object
189
+ #
190
+ # @param klass [Class] the Ruby type that we want to assign as value
191
+ #
192
+ # @param options [Hash] a set of options to customize the mapping
193
+ # @option options [Symbol] :as the name of the original column
194
+ #
195
+ # @since 0.1.0
196
+ #
197
+ # @example Default schema
198
+ # require 'lotus/model'
199
+ #
200
+ # # Given the following schema:
201
+ # #
202
+ # # CREATE TABLE users (
203
+ # # id integer NOT NULL,
204
+ # # name varchar(64),
205
+ # # );
206
+ # #
207
+ # # And the following entity:
208
+ # #
209
+ # # class User
210
+ # # include Lotus::Entity
211
+ # # self.attributes = :name
212
+ # # end
213
+ #
214
+ # mapper = Lotus::Model::Mapper.new do
215
+ # collection :users do
216
+ # entity User
217
+ #
218
+ # attribute :id, Integer
219
+ # attribute :name, String
220
+ # end
221
+ # end
222
+ #
223
+ # # The first argument (`:name`) always corresponds to the `User`
224
+ # # attribute.
225
+ #
226
+ # # The second one (`:klass`) is the Ruby type that we want for our
227
+ # # attribute.
228
+ #
229
+ # # We don't need to use `:as` because the database columns match the
230
+ # # `User` attributes.
231
+ #
232
+ # @example Customized schema
233
+ # require 'lotus/model'
234
+ #
235
+ # # Given the following schema:
236
+ # #
237
+ # # CREATE TABLE articles (
238
+ # # i_id integer NOT NULL,
239
+ # # i_user_id integer NOT NULL,
240
+ # # s_title varchar(64),
241
+ # # comments_count varchar(8) # Not an error: it's for String => Integer coercion
242
+ # # );
243
+ # #
244
+ # # And the following entity:
245
+ # #
246
+ # # class Article
247
+ # # include Lotus::Entity
248
+ # # self.attributes = :user_id, :title, :comments_count
249
+ # # end
250
+ #
251
+ # mapper = Lotus::Model::Mapper.new do
252
+ # collection :articles do
253
+ # entity Article
254
+ #
255
+ # attribute :id, Integer, as: :i_id
256
+ # attribute :user_id, Integer, as: :i_user_id
257
+ # attribute :title, String, as: :s_title
258
+ # attribute :comments_count, Integer
259
+ #
260
+ # identity :i_id
261
+ # end
262
+ # end
263
+ #
264
+ # # The first argument (`:name`) always corresponds to the `Article`
265
+ # # attribute.
266
+ #
267
+ # # The second one (`:klass`) is the Ruby type that we want for our
268
+ # # attribute.
269
+ #
270
+ # # The third option (`:as`) is mandatory only when the database
271
+ # # column doesn't match the name of the mapped attribute.
272
+ # #
273
+ # # For instance: we need to use it for translate `:s_title` to
274
+ # # `:title`, but not for `:comments_count`.
275
+ def attribute(name, klass, options = {})
276
+ @attributes[name] = [klass, (options.fetch(:as) { name }).to_sym]
277
+ end
278
+
279
+ # Serializes an entity to be persisted in the database.
280
+ #
281
+ # @param entity [Object] an entity
282
+ #
283
+ # @api private
284
+ # @since 0.1.0
285
+ def serialize(entity)
286
+ @coercer.to_record(entity)
287
+ end
288
+
289
+ # Deserialize a set of records fetched from the database.
290
+ #
291
+ # @param records [Array] a set of raw records
292
+ #
293
+ # @api private
294
+ # @since 0.1.0
295
+ def deserialize(records)
296
+ records.map do |record|
297
+ @coercer.from_record(record)
298
+ end
299
+ end
300
+
301
+ # Deserialize only one attribute from a raw value.
302
+ #
303
+ # @param attribute [Symbol] the attribute name
304
+ # @param value [Object,nil] the value to be coerced
305
+ #
306
+ # @api private
307
+ # @since 0.1.0
308
+ def deserialize_attribute(attribute, value)
309
+ @coercer.public_send(:"deserialize_#{ attribute }", value)
310
+ end
311
+
312
+ # Loads the internals of the mapper, in order to guarantee thread safety.
313
+ #
314
+ # @api private
315
+ # @since 0.1.0
316
+ def load!
317
+ @coercer = coercer_class.new(self)
318
+ configure_repository!
319
+ end
320
+
321
+ private
322
+ # Assigns a repository to an entity
323
+ #
324
+ # @see Lotus::Repository
325
+ #
326
+ # @api private
327
+ # @since 0.1.0
328
+ def configure_repository!
329
+ repository = Object.const_get("#{ entity.name }#{ REPOSITORY_SUFFIX }")
330
+ repository.collection = name
331
+ rescue NameError
332
+ end
333
+ end
334
+ end
335
+ end
336
+ end