lotus-model 0.0.0 → 0.1.0

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 (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