lotus-model 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f8aeb016a4308c564ac6a9da4d20dad73669e64
4
- data.tar.gz: 8a63dbd06ddc13e1c78db5c9961e26a2ace6006b
3
+ metadata.gz: ae1042adba4d02f0e12ad69ccb025061603a3b24
4
+ data.tar.gz: 0c976c625163281c1d8e03409f1ff79db9838ba6
5
5
  SHA512:
6
- metadata.gz: 16812c63f5ae325e6be21362f00a37aa9e926356119ffafbb6e76823f342db5f18b5a9d1a6a8d4d302045b6c2c72d64e5fa167fda344823664eb056b52efa2e5
7
- data.tar.gz: dea5481126a0c5104d68335cfe294199c7183f2ba30209e173184d00d490c98bd567d9057f790c2e336cba4baf9da66648c13cd84310c9b9da433195ea28ef04
6
+ metadata.gz: 91017c7d534780cb9dd7004969835762c1185596845ac8b9a968d762af7913709ddfbd17d5b68daea1c6851152a3b45e6135d2b23b65f548619b77f22a5d8ec5
7
+ data.tar.gz: 5a40607f634bdea786e3d2f6005d14acc5f27160f01bb6cb0a0f028414a1163bb0612131ba8554cd1264bcfa7086be853054f7e246d55ff17d9797b7ebe83335
data/CHANGELOG.md CHANGED
@@ -1,168 +1,52 @@
1
- ## v0.1.2
2
- ### Jun 26, 2014
3
-
4
- 27eef39 2014-06-26 **Luca Guidi** Bump version to 0.1.2
5
-
6
- afc33eb 2014-06-24 **Stanislav Spiridonov** Fix Coercions require
7
-
8
- f5778e4 2014-05-22 **Krzysztof Zalewski** Entity defines #id accessor by default
9
-
10
- ## v0.1.1
11
- ### Jun 23, 2014
12
-
13
- 99ea094 2014-06-13 **Luca Guidi** Introduced Lotus::Model::Mapping::Coercions in order to decouple from Lotus::Utils::Kernel
14
-
15
- 3fa2693 2014-05-10 **Luca Guidi** Support for Ruby 2.1.2
16
-
17
- 3682552 2014-04-25 **Peter Suschlik** Iterate over each value using `each_value`
18
-
19
- cce7746 2014-04-24 **Peter Suschlik** Just extend the base class. No need to class_eval
20
-
21
- 719e03c 2014-04-24 **Peter Suschlik** Pass list of attributes to `attr_accessor`
22
-
23
- ## v0.1.0
24
- ### Apr 23, 2014
25
-
26
- ec395d8 2014-04-22 **Luca Guidi** Added an accessor to introspect Mapper collections
27
-
28
- 96d9d00 2014-04-18 **Luca Guidi** Allow queries to be composed
29
-
30
- a7d64c1 2014-04-18 **Damir Zekic** Don't serialize identity column if it's nil
31
-
32
- 8484941 2014-04-17 **Luca Guidi** Fixed Sql::Collection#select for Ruby 2.0.0
33
-
34
- bd9d679 2014-04-17 **Luca Guidi** Allow Sql#Query#order and #desc to accept multiple columns and/or multiple invokations.
35
-
36
- b6a7af8 2014-04-16 **Luca Guidi** Enforce Adapter interface with #command and #query
37
-
38
- 3787f33 2014-04-16 **Luca Guidi** Allow Mapper to accept a custom coercer for the database
39
-
40
- 893109a 2014-04-15 **Luca Guidi** Ensure that unmapped attributes doens't interfer with initialization of entities
41
-
42
- da37d7a 2014-04-15 **Luca Guidi** Implemented Memory::Query #to_s, #empty? and #any?
43
-
44
- 94f0ecb 2014-04-15 **Luca Guidi** Implemented Repository#exclude
45
-
46
- 6998328 2014-04-15 **Luca Guidi** Removed unused require
47
-
48
- 7211935 2014-04-15 **Luca Guidi** Implemented Sql::Query #to_s, #empty? and #any?
49
-
50
- 5e7e0c4 2014-04-15 **Luca Guidi** Implemented Sql::Query#negate!
51
-
52
- 5df30c2 2014-04-15 **Luca Guidi** Define top level constant ::Boolean
53
-
54
- a9df2ec 2014-04-15 **Luca Guidi** Load Mapper when the framework is loaded
55
-
56
- de21101 2014-04-15 **Luca Guidi** Extracted Mapping::Collection::REPOSITORY_SUFFIX constant
57
-
58
- b4ed0fe 2014-04-15 **Luca Guidi** Expose Mapper#load! to make Lotus::Model thread safe
59
-
60
- 0936848 2014-04-14 **Luca Guidi** Moved UnmappedCollectionError under a separated file
61
-
62
- b6e49ff 2014-04-14 **Luca Guidi** Removed serialization responsibility from Mapper
63
-
64
- 9057fbd 2014-04-14 **Luca Guidi** Removed unnecessary conditional in test
65
-
66
- 43c462f 2014-04-14 **Luca Guidi** Renamed Lotus::Model::Mapping::Collection#key into #identity
67
-
68
- af59039 2014-04-14 **Luca Guidi** Removed serialization responsibility from Sql::Command
69
-
70
- 92101bb 2014-04-14 **Luca Guidi** Removed deserialization responsibility from Sql::Query
71
-
72
- 04e9597 2014-04-14 **Luca Guidi** Rewritten Sql::Command, it now works on scoped queries
73
-
74
- eb49746 2014-04-14 **Luca Guidi** Coerce with the right type the primary key for Repository.find
75
-
76
- daf3e04 2014-04-14 **Luca Guidi** Implemented Command for mutation actions such as insert, update, delete. Removed serialization responsibility to the adapter. Removed unused code.
77
-
78
- 5ae8b11 2014-04-13 **Luca Guidi** Sql and Memory adapter are now using Query to serve #all, #find, #first, #last
79
-
80
- b0a35c5 2014-04-13 **Luca Guidi** Implemented Query#asc and #desc
81
-
82
- ef2d1fa 2014-04-13 **Luca Guidi** Make querying thread safe for MemoryAdapter
83
-
84
- db7e699 2014-04-12 **Luca Guidi** Implemented Query#select
85
-
86
- 2d83581 2014-04-12 **Luca Guidi** Implemented Query#exist?
87
-
88
- 13cfde0 2014-04-12 **Luca Guidi** Implemented Query#exclude
89
-
90
- 79596de 2014-04-12 **Luca Guidi** Implemented Query#range
91
-
92
- 70df238 2014-04-12 **Luca Guidi** Implemented Query#interval
93
-
94
- a0cbb8c 2014-04-12 **Luca Guidi** Implemented Query#min
95
-
96
- 41e3d69 2014-04-12 **Luca Guidi** Implemented Query#max
97
-
98
- 5577283 2014-04-12 **Luca Guidi** Changed the semantic of Query#average: let return a float if needed, handle strings and nil values
99
-
100
- 3e1bddc 2014-04-12 **Luca Guidi** Implemented Query#sum
101
-
102
- 97d0fb9 2014-04-12 **Luca Guidi** Implemented Lotus::Model::Adapters::Memory::Query#average
103
-
104
- d7068b5 2014-04-12 **Luca Guidi** Implemented Lotus::Model::Adapters::Sql::Query#average
105
-
106
- 21abc27 2014-04-10 **Luca Guidi** Introduced Sql::Query
107
-
108
- 7b63b7f 2014-04-10 **Luca Guidi** Implemented Memory::Query#count
109
-
110
- 517a89a 2014-04-10 **Luca Guidi** Make the results of Repository queries lazy
111
-
112
- e6a756c 2014-04-10 **Luca Guidi** Renamed adapters with the "Adapter" suffix, in order to keep namespaces free.
113
-
114
- 8a076b9 2014-04-10 **Luca Guidi** Implemented Query#or, #limit and #offset
115
-
116
- 388957d 2014-04-09 **Luca Guidi** Added tests for SQL adapter and implemented #where, #and and #order for all the adapters
117
-
118
- 5a97c12 2014-04-09 **Luca Guidi** Initial design for quering the datasource
119
-
120
- 6f804db 2014-04-08 **Luca Guidi** Use Lotus::Utils::Kernel conversions
121
-
122
- 4ae6967 2014-04-07 **Luca Guidi** Allow the mapper to specify the primary key of a collection with Lotus::Model::Mapper::Collection#key.
123
-
124
- 85def40 2014-04-07 **Luca Guidi** Extracted Lotus::Model::Adapters::Memory::Collection::PrimaryKey
125
-
126
- ff8d6d4 2014-04-07 **Luca Guidi** Lotus::Repository.collection is now configured by the framework internals.
127
-
128
- 122e040 2014-04-02 **Luca Guidi** Introduced attributes mapping and (de)serializations policies based on it.
129
-
130
- f925ebc 2014-03-26 **Luca Guidi** Lotus::Entity#id is always the primary key
131
-
132
- 0bf8bb5 2014-03-26 **Luca Guidi** Introduced Lotus::Model::Adapters::Sql
133
-
134
- cfbed99 2014-03-26 **Luca Guidi** Lotus::Model::Repository => Lotus::Repository
135
-
136
- 3a72d68 2014-03-26 **Luca Guidi** Lotus::Model::Entity => Lotus::Entity
137
-
138
- ed29d2d 2014-03-26 **Luca Guidi** Preload Lotus::Model::Repository
139
-
140
- f1bda7f 2014-03-26 **Luca Guidi** Improved tests and better semantic for Lotus::Model::Repository
141
-
142
- 65b8e1a 2014-03-26 **Luca Guidi** Tests and thready safety for Lotus::Model::Adapters::Memory
143
-
144
- 63d9fc5 2014-03-26 **Luca Guidi** When generate Entity#initialize use class attribute 'attributes', instead of the homonym argument
145
-
146
- 442987d 2014-02-17 **Luca Guidi** Lotus::Model::Repository.find raises a Lotus::Model::RecordNotFound exception if it can't find a record, associated with the given ID
147
-
148
- c2b94e0 2014-02-15 **Luca Guidi** Ensure memory adapted is able to find a record for a string id
149
-
150
- b258ea0 2014-02-07 **Luca Guidi** Make Repository to work with entities
151
-
152
- 0371b41 2014-02-05 **Luca Guidi** Implemented Entity
153
-
154
- 9d2bfe3 2014-02-05 **Luca Guidi** Renamed "object" in "entity" in method signatures. Repositories and adapters work on objects that are aware of the identity's concept.
155
-
156
- be0e4e0 2014-02-05 **Luca Guidi** Extracted Abstract adapter and made Memory to inherit from it
157
-
158
- 3ca28af 2014-02-05 **Luca Guidi** Let Repository to delegate operations to the current adapter
159
-
160
- 3318bd1 2014-02-05 **Luca Guidi** Made Repository methods to accept one object instead of a collection
161
-
162
- baf378a 2014-02-05 **Luca Guidi** Implemented Repository.delete
163
-
164
- 1b8c0a0 2014-02-05 **Luca Guidi** Implemented Repository.persist, .create and .update
165
-
166
- c6bde87 2014-02-05 **Luca Guidi** Implemented Repository.find
167
-
168
- a45248f 2014-02-05 **Luca Guidi** Initial mess
1
+ # Lotus::Model
2
+ A persistence layer for Lotus
3
+
4
+ ## v0.2.0 - 2014-12-23
5
+ ### Added
6
+ - [Luca Guidi] Introduced file system adapter
7
+ – [Benny Klotz & Trung Lê] Introduced `Entity` inheritance of attributes
8
+ - [Trung Lê] Introduced `Entity#update` for bulk update of attributes
9
+ - [Luca Guidi] Improved error when try to use a repository which wasn't configured or when the framework wasn't loaded yet
10
+ - [Trung Lê] Introduced `Entity#to_h`
11
+ - [Trung Lê] Introduced `Lotus::Model.duplicate`
12
+ - [Trung Lê] Made `Lotus::Mapper` lazy
13
+ - [Trung Lê] Introduced thread safe autoloading for adapters
14
+ - [Felipe Sere] Add support for `Symbol` coercion
15
+ - [Celso Fernandes] Add support for `BigDecimal` coercion
16
+ - [Trung Lê] Introduced `Lotus::Model.load!` as entry point for loading
17
+ - [Trung Lê] Introduced `Mapper#repository` as DSL to associate a repository to a collection
18
+ - [Trung Lê & Tao Guo] Introduced `Configuration#mapping` as DSL to configure the mapping
19
+ - [Coen Wessels] Allow `where`, `exclude` and `or` to accept blocks
20
+ - [Trung Lê & Tao Guo] Introduced `Configuration#adapter` as DSL to configure the adapter
21
+ - [Trung Lê] Introduced `Lotus::Model::Configuration`
22
+
23
+ ### Changed
24
+ - [Trung Lê] Changed `Entity.attributes=` to `Entity.attributes`
25
+ - [Trung Lê] In case of missing entity, let `Repository#find` returns `nil` instead of raise an exception
26
+
27
+ ### Fixed
28
+ - [Rik Tonnard] Ensure correct behavior of `#offset` in memory adapter
29
+ - [Benny Klotz] Ensure `Entity` to set the attributes even when the given Hash uses strings as keys
30
+ - [Ben Askins] Always return the entity from `Repository#persist`
31
+ - [Jeremy Stephens] Made `Memory::Query#where` and `#or` behave more like the SQL counter-part
32
+
33
+ ## v0.1.2 - 2014-06-26
34
+ ### Fixed
35
+ - [Stanislav Spiridonov] Ensure to require `'lotus/model/mapping/coercions'`
36
+ - [Krzysztof Zalewski] `Entity` defines `#id` accessor by default
37
+
38
+
39
+ ## v0.1.1 - 2014-06-23
40
+ ### Added
41
+ - [Luca Guidi] Introduced `Lotus::Model::Mapping::Coercions` in order to decouple from `Lotus::Utils::Kernel`
42
+ - [Luca Guidi] Official support for Ruby 2.1
43
+
44
+ ## v0.1.0 - 2014-04-23
45
+ ### Added
46
+ - [Luca Guidi] Allow to inject coercer into mapper
47
+ - [Luca Guidi] Introduced database mapping
48
+ - [Luca Guidi] Introduced `Lotus::Entity`
49
+ - [Luca Guidi] Introduced SQL adapter
50
+ - [Luca Guidi] Introduced memory adapter
51
+ – [Luca Guidi] Introduced adapters for repositories
52
+ - [Luca Guidi] Introduced `Lotus::Repository`
data/EXAMPLE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Lotus::Model
2
2
 
3
- This is a guide that helps you to getting started with [**Lotus::Model**](https://github.com/lotus/model).
3
+ This is a guide that helps you to get started with [**Lotus::Model**](https://github.com/lotus/model).
4
4
  You can find the full code source [here](https://gist.github.com/jodosha/11211048).
5
5
 
6
6
  ## Gems
@@ -18,8 +18,12 @@ Then we can fetch the dependencies with `bundle install`.
18
18
 
19
19
  ## Setup
20
20
 
21
- **Lotus::Model** doesn't have migrations, for this example we're gonna use [Sequel](http://sequel.jeremyevans.net).
22
- We create the database first, and then two tables: `authors` and `articles`.
21
+ <a name="connection-url"></a>
22
+
23
+ **Lotus::Model** doesn't have migrations.
24
+ For this example we will use [Sequel](http://sequel.jeremyevans.net).
25
+ We create the database first.
26
+ Then we create two tables: `authors` and `articles`.
23
27
 
24
28
  ```ruby
25
29
  require 'bundler/setup'
@@ -60,7 +64,7 @@ end
60
64
 
61
65
  class Article
62
66
  include Lotus::Entity
63
- self.attributes = :author_id, :title, :comments_count, :published # id is implicit
67
+ attributes :author_id, :title, :comments_count, :published # id is implicit
64
68
 
65
69
  def published?
66
70
  !!published
@@ -111,7 +115,7 @@ class ArticleRepository
111
115
  end
112
116
 
113
117
  def self.best_article_ever
114
- rank.limit(1)
118
+ rank.limit(1).first
115
119
  end
116
120
 
117
121
  def self.comments_average
@@ -120,48 +124,38 @@ class ArticleRepository
120
124
  end
121
125
  ```
122
126
 
123
- ## Mapper
124
-
125
- We create a correspondence between the database columns with the entities' attributes.
127
+ ## Loading
126
128
 
127
129
  ```ruby
128
- mapper = Lotus::Model::Mapper.new do
129
- collection :authors do
130
- entity Author
131
-
132
- attribute :id, Integer
133
- attribute :name, String
134
- end
130
+ Lotus::Model.configure do
131
+ adapter type: :sql, uri: connection_uri
135
132
 
136
- collection :articles do
137
- entity Article
133
+ mapping do
134
+ collection :authors do
135
+ entity Author
136
+ repository AuthorRepository
138
137
 
139
- attribute :id, Integer
140
- attribute :author_id, Integer
141
- attribute :title, String
142
- attribute :comments_count, Integer
143
- attribute :published, Boolean
144
- end
145
- end
146
- ```
147
-
148
- ## Loading
138
+ attribute :id, Integer
139
+ attribute :name, String
140
+ end
149
141
 
150
- We create an adapter instance, passing `mapper` and the connection URI (see above).
151
- Please remember that the setup code is only required for the standalone usage of **Lotus::Model**.
152
- A **Lotus** application will handle that configurations for you.
142
+ collection :articles do
143
+ entity Article
144
+ repository ArticleRepository
153
145
 
154
- ```ruby
155
- adapter = Lotus::Model::Adapters::SqlAdapter.new(mapper, connection_uri)
156
- AuthorRepository.adapter = adapter
157
- ArticleRepository.adapter = adapter
158
-
159
- mapper.load! # last operation
146
+ attribute :id, Integer
147
+ attribute :author_id, Integer
148
+ attribute :title, String
149
+ attribute :comments_count, Integer
150
+ attribute :published, Boolean
151
+ end
152
+ end
153
+ end.load!
160
154
  ```
161
155
 
162
156
  ## Persist
163
157
 
164
- Let's instantiate and persist some objects for our example:
158
+ We instantiate and persist an `Author` and a few `Articles` for our example:
165
159
 
166
160
  ```ruby
167
161
  author = Author.new(name: 'Luca')
@@ -181,7 +175,7 @@ end
181
175
 
182
176
  ## Query
183
177
 
184
- We can use repositories to query the database and return the entities we're looking for:
178
+ We use the repositories to query the database and return the entities we're looking for:
185
179
 
186
180
  ```ruby
187
181
  ArticleRepository.first # => return the first article
@@ -200,10 +194,11 @@ ArticleRepository.most_recent_by_author(author) # => most recent articles by an
200
194
  ArticleRepository.most_recent_published_by_author(author) # => most recent published articles by an author
201
195
  ```
202
196
 
203
- ## Business logic
197
+ ## Business Logic
204
198
 
205
199
  As we've seen above, `Article` implements an API for publishing.
206
- We're gonna use that logic to alter the state of an article (from draft to published) and then we use the repository to persist this new state.
200
+ We use that logic to alter the state of an article (from draft to published).
201
+ We then use the repository to persist this new state.
207
202
 
208
203
  ```ruby
209
204
  article = ArticleRepository.drafts.first
data/README.md CHANGED
@@ -41,7 +41,9 @@ __Lotus::Model__ supports Ruby (MRI) 2+
41
41
 
42
42
  Add this line to your application's Gemfile:
43
43
 
44
- gem 'lotus-model'
44
+ ```ruby
45
+ gem 'lotus-model'
46
+ ```
45
47
 
46
48
  And then execute:
47
49
 
@@ -53,9 +55,52 @@ Or install it yourself as:
53
55
 
54
56
  ## Usage
55
57
 
58
+ This class provides a DSL to configure adapter, mapping and collection.
59
+
60
+ ```ruby
61
+ require 'lotus/model'
62
+
63
+ class User
64
+ include Lotus::Entity
65
+ attributes :name, :age
66
+ end
67
+
68
+ class UserRepository
69
+ include Lotus::Repository
70
+ end
71
+
72
+ Lotus::Model.configure do
73
+ adapter type: :sql, uri: 'postgres://localhost/database'
74
+
75
+ mapping do
76
+ collection :users do
77
+ entity User
78
+ respository UserRepository
79
+
80
+ attribute :id, Integer
81
+ attribute :name, String
82
+ attribute :age, Integer
83
+ end
84
+ end
85
+ end
86
+
87
+ Lotus::Model.load!
88
+
89
+ user = User.new(name: 'Luca', age: 32)
90
+ user = UserRepository.create(user)
91
+
92
+ puts user.id # => 1
93
+
94
+ u = UserRepository.find(user.id)
95
+ u == user # => true
96
+ ```
97
+
98
+ ## Concepts
99
+
56
100
  ### Entities
57
101
 
58
102
  An object that is defined by its identity.
103
+ See "Domain Driven Design" by Eric Evans.
59
104
 
60
105
  An entity is the core of an application, where the part of the domain logic is implemented.
61
106
  It's a small, cohesive object that expresses coherent and meaningful behaviors.
@@ -72,17 +117,17 @@ require 'lotus/model'
72
117
 
73
118
  class Person
74
119
  include Lotus::Entity
75
- self.attributes = :name, :age
120
+ attributes :name, :age
76
121
  end
77
122
  ```
78
123
 
79
- When a class includes `Lotus::Entity` it will receive the following interface:
124
+ When a class includes `Lotus::Entity` it receives the following interface:
80
125
 
81
126
  * `#id`
82
127
  * `#id=`
83
128
  * `#initialize(attributes = {})`
84
129
 
85
- Also, the usage of `.attributes=` defines accessors for the given attribute names.
130
+ `Lotus::Entity` also provides the `.attributes` for defining attribute accessors for the given names.
86
131
 
87
132
  If we expand the code above in **pure Ruby**, it would be:
88
133
 
@@ -96,8 +141,32 @@ class Person
96
141
  end
97
142
  ```
98
143
 
99
- Indeed, **Lotus::Model** ships `Entity` only for developers's convenience, but the
100
- rest of the framework is able to accept any object that implements the interface above.
144
+ **Lotus::Model** ships `Lotus::Entity` for developers's convenience.
145
+
146
+ **Lotus::Model** depends on a narrow and well-defined interface for an Entity - `#id`, `#id=`, `#initialize(attributes={})`.
147
+ If your object implements that interface then that object can be used as an Entity in the **Lotus::Model** framework.
148
+
149
+ However, we suggest to implement this interface by including `Lotus::Entity`, in case that future versions of the framework will expand it.
150
+
151
+ See [Dependency Inversion Principle](http://en.wikipedia.org/wiki/Dependency_inversion_principle) for more on interfaces.
152
+
153
+ When a class extend an entity class, it will also *inherit* its mother's attributes.
154
+
155
+ ```ruby
156
+ require 'lotus/model'
157
+
158
+ class Article
159
+ include Lotus::Entity
160
+ attributes :name
161
+ end
162
+
163
+ class RareArticle < Article
164
+ attributes :price
165
+ end
166
+ ```
167
+
168
+ That is, `RareArticle`'s attributes carry over `:name` attribute from `Article`,
169
+ thus is `:id, :name, :price`.
101
170
 
102
171
  ### Repositories
103
172
 
@@ -138,7 +207,7 @@ When a class includes `Lotus::Repository`, it will receive the following interfa
138
207
  It corresponds to a table for a SQL database or to a MongoDB collection.
139
208
 
140
209
  **All the queries are private**.
141
- This decision forces developers to define intention revealing API, instead leak storage API details outside of a repository.
210
+ This decision forces developers to define intention revealing API, instead of leaking storage API details outside of a repository.
142
211
 
143
212
  Look at the following code:
144
213
 
@@ -229,6 +298,28 @@ class ArticleRepository
229
298
  end
230
299
  ```
231
300
 
301
+ **Your models and repositories have to be in the same namespace.** Otherwise `Lotus::Model::Mapper#load!`
302
+ will not initialize your repositories correctly.
303
+
304
+ ```ruby
305
+ class MyLotusApp::Model::User
306
+ include Lotus::Entity
307
+ # your code here
308
+ end
309
+
310
+ # This repository will work...
311
+ class MyLotusApp::Model::UserRepository
312
+ include Lotus::Repository
313
+ # your code here
314
+ end
315
+
316
+ # ...this will not!
317
+ class MyLotusApp::Repository::UserRepository
318
+ include Lotus::Repository
319
+ # your code here
320
+ end
321
+ ```
322
+
232
323
  ### Data Mapper
233
324
 
234
325
  A persistence mapper that keeps entities independent from database details.
@@ -250,19 +341,53 @@ mapper = Lotus::Model::Mapper.new do
250
341
  end
251
342
  ```
252
343
 
253
- For simplicity sake, imagine that the mapper above is used with a SQL database.
344
+ For simplicity's sake, imagine that the mapper above is used with a SQL database.
254
345
  We use `#collection` to indicate the name of the table that we want to map, `#entity` to indicate the class that we want to associate.
255
- In the end, each `#attribute` call, is to associate the column with a Ruby type.
346
+ In the end, each call to `#attribute` associates the specified column with a corresponding Ruby type.
256
347
 
257
348
  For advanced mapping and legacy databases, please have a look at the API doc.
258
349
 
350
+ **Known limitations**
351
+
352
+ Please be noted there are limitations with inherited entities:
353
+
354
+ ```ruby
355
+ require 'lotus/model'
356
+
357
+ class Article
358
+ include Lotus::Entity
359
+ attributes :name
360
+ end
361
+
362
+ class RareArticle < Article
363
+ attributes :price
364
+ end
365
+
366
+ mapper = Lotus::Model::Mapper.new do
367
+ collection :articles do
368
+ entity Article
369
+
370
+ attribute :id, Integer
371
+ attribute :name, String
372
+ attribute :price, Integer
373
+ end
374
+ end
375
+ ```
376
+
377
+ In the example above, there are few problems:
378
+
379
+ * `Article` could not be fetched because mapping could not map `price`.
380
+ * Finding a persisted `RareArticle` record, for eg. `ArticleRepository.find(123)`,
381
+ the result is an `Article` not `RareArticle`.
382
+
259
383
  ### Adapter
260
384
 
261
385
  An adapter is a concrete implementation of persistence logic for a specific database.
262
- **Lotus::Model** is shipped with two adapters:
386
+ **Lotus::Model** is shipped with three adapters:
263
387
 
264
388
  * SqlAdapter
265
389
  * MemoryAdapter
390
+ * FileSystemAdapter
266
391
 
267
392
  An adapter can be associated with one or multiple repositories.
268
393
 
@@ -286,7 +411,7 @@ In the example above, we reuse the adapter because the target tables (`people` a
286
411
 
287
412
  ### Query
288
413
 
289
- An object that implements an interface for quering the database.
414
+ An object that implements an interface for querying the database.
290
415
  This interface may vary, according to the adapter's specifications.
291
416
  Think of an adapter for Redis, it will probably employ different strategies to filter records than an SQL query object.
292
417
 
@@ -294,6 +419,21 @@ Think of an adapter for Redis, it will probably employ different strategies to f
294
419
 
295
420
  * A repository must be named after an entity, by appending `"Repository"` to the entity class name (eg. `Article` => `ArticleRepository`).
296
421
 
422
+ ### Configurations
423
+
424
+ * Non-standard respository can be configured for an entity, by setting `repository` on the collection.
425
+
426
+ ```ruby
427
+ require 'lotus/model'
428
+
429
+ mapper = Lotus::Model::Mapper.new do
430
+ collection :users do
431
+ entity User
432
+ repository EmployeeRepository
433
+ end
434
+ end
435
+ ```
436
+
297
437
  ### Thread safety
298
438
 
299
439
  **Lotus::Model**'s is thread safe during the runtime, but it isn't during the loading process.
@@ -301,7 +441,7 @@ The mapper compiles some code internally, be sure to safely load it before your
301
441
 
302
442
  ```ruby
303
443
  Mutex.new.synchronize do
304
- mapper.load!
444
+ Lotus::Model.load!
305
445
  end
306
446
  ```
307
447