thingtank 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +37 -0
- data/VERSION +1 -1
- data/lib/thingtank/character.rb +17 -3
- data/lib/thingtank/character_handling.rb +4 -0
- data/lib/thingtank/dependencies.rb +22 -0
- data/lib/thingtank/instance_methods.rb +8 -0
- data/test/test_fakebase.rb +17 -1
- metadata +29 -29
data/README.md
CHANGED
@@ -283,6 +283,43 @@ since julius is immortal, no one should be able to destroy him:
|
|
283
283
|
You may subclass ThingTank to do further separation and mix the
|
284
284
|
native properties of ThingTanks / its subclasses with the characters properties.
|
285
285
|
|
286
|
+
Hints:
|
287
|
+
-----------------------------------------------
|
288
|
+
|
289
|
+
The main idea is that every couch document could have many characters at the same time.
|
290
|
+
The implementation is that the document is an object of ThingTank or a subclass of it. ThingTank is compatible to couchrest_model with some helper methods.
|
291
|
+
Most of the time you don't want to define properties for the ThingTank class or a subclass. You may store any key => value freely within the document by
|
292
|
+
using the [] and []= methods.
|
293
|
+
|
294
|
+
The concept is inspired by the way the go language defines interfaces. With _ThingTank_ you may thing of the main doc as a _Hash_. Then the characters are
|
295
|
+
"interfaces", that define which properties a doc would need to fullfill the character ("to have the character"). But that alone is not suffient. You also
|
296
|
+
need to tell the doc that it will have the character from now on. This information will be stored in the "characters" property of the doc. You might remove this
|
297
|
+
statement with or without affecting the properties the character cares about. But only if the doc should have the character you might interact with the subseet of his
|
298
|
+
properties that the character cares about via the character. A doc might combine different characters at the same time. There might be even different characters that
|
299
|
+
care about the same properties. If so you should take care that there are no conflicting actions taking place at the same update.
|
300
|
+
|
301
|
+
The characters are all subclasses of the ThingTank::Character class and are compatible with couchrest_model as well but they won't interact with the database
|
302
|
+
directly but only via their document (instance of ThingTank). The characters is where all validation, callbacks, properties and additional methods should go into.
|
303
|
+
They do all the hard work, but they aren't loaded automatically but only if you call them via the _ThingTank#as_ method. Then the properties that they care about
|
304
|
+
are copied from the doc to the character instance. When you interact with the character object its properties go out of sync with the original doc so here are some hints
|
305
|
+
how to handle this dirty state and how to get them back to the doc.
|
306
|
+
|
307
|
+
Characters may also interact via the doc, but care has to be taken in order to save the changes back to doc properly and to inform the affected character about the changes.
|
308
|
+
|
309
|
+
* Use _Character#to\_doc_ to return the changed date from the character to the doc without saving the doc.
|
310
|
+
* Use _Character#reload_ to load the (possibly changed) data from the doc to the character object.
|
311
|
+
* Use _Character#reload!_ to load the (possibly changed) data from the database. The doc with be reloaded from the database and then fill the character object.
|
312
|
+
* Use _Character#save_ or _ThingTank#save_ to save the doc with all changes
|
313
|
+
* Use _ThingTank#add\_character_ to add a Character and pass it a code block, so that all the changes go back to the doc at the end of the code block
|
314
|
+
* Use _ThingTank#as_ to work with a certain character of the doc and pass it a code block, so that all the changes go back to the doc at the end of the code block
|
315
|
+
* Use _ThingTank#is_ if the properties for the character are already in the doc and you just want it to let it have the character
|
316
|
+
* Use _ThingTank#get_ to get the doc out of the database (and then use _ThingTank#as_ to handle it as a character)
|
317
|
+
* Views are stored and called via the _ThingTank_ class
|
318
|
+
* Pass _ThingTank#add\_character_ as second parameter the name of the property if you want the doc to have a property that has a certain character
|
319
|
+
* Use _ThingTank#with_ to use the character of a certain property
|
320
|
+
* Use the _doc method with a character method to access the doc and _doc.id for the id
|
321
|
+
* Look at the examples and tests
|
322
|
+
|
286
323
|
|
287
324
|
Contributing to thingtank
|
288
325
|
--------------------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
data/lib/thingtank/character.rb
CHANGED
@@ -92,23 +92,37 @@ class ThingTank
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
# use to_doc to put characters changes back to the doc without saving the doc
|
96
|
+
def to_doc
|
96
97
|
if changed?
|
97
98
|
changed_to_character_hash().each do |k,v|
|
98
99
|
_character_doc[k] = v
|
99
100
|
end
|
101
|
+
@changed_attributes.clear if @changed_attributes
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def flush_to_doc
|
106
|
+
if changed?
|
107
|
+
to_doc
|
100
108
|
_character_doc.save
|
101
|
-
@changed_attributes.clear
|
102
109
|
end
|
103
110
|
end
|
104
111
|
|
112
|
+
# use reload to get the latest properties from the doc without reloading all from the database
|
105
113
|
def reload
|
106
114
|
attrs = _character_doc.as(self.class).to_character_hash
|
107
115
|
prepare_all_attributes(attrs, :directly_set_attributes => true)
|
108
|
-
@changed_attributes.clear
|
116
|
+
@changed_attributes.clear if @changed_attributes
|
109
117
|
self
|
110
118
|
end
|
111
119
|
|
120
|
+
# use reload! to get the latest properties from the database, the doc will be reloaded and the character to
|
121
|
+
def reload!
|
122
|
+
_character_doc.reload
|
123
|
+
reload
|
124
|
+
end
|
125
|
+
|
112
126
|
def to_character(klass, key, &code)
|
113
127
|
_character_doc.to_character(klass, key, &code)
|
114
128
|
end
|
@@ -147,6 +147,10 @@ class ThingTank
|
|
147
147
|
@dependencies.add_character(klass) if add_character && key.nil?
|
148
148
|
character = key ? property_to_character(key, klass) : FakeBase.new(self, klass, add_character).get()
|
149
149
|
(code.call(character) ; character.flush_to_doc) if code
|
150
|
+
# we don't do this. there is no proper way to update all given characters
|
151
|
+
# one must not rely on a character properties after the doc has been manipulated
|
152
|
+
# use Character#reload to get the latest from the doc object to the character and Character#reload! to reload the doc from the database and reload the character then
|
153
|
+
#@dependencies.add_character_object(character)
|
150
154
|
character
|
151
155
|
end
|
152
156
|
|
@@ -7,6 +7,8 @@ class ThingTank
|
|
7
7
|
@registration = []
|
8
8
|
@save = []
|
9
9
|
@children = {}
|
10
|
+
#@character_objects = []
|
11
|
+
#@just_reloaded = []
|
10
12
|
end
|
11
13
|
|
12
14
|
attr_reader :parent
|
@@ -19,6 +21,26 @@ class ThingTank
|
|
19
21
|
@registration.each { |character| @doc.register_character(character) }
|
20
22
|
end
|
21
23
|
|
24
|
+
# we don't do this. there is no proper way to update all given characters
|
25
|
+
# one must not rely on a character properties after the doc has been manipulated
|
26
|
+
# use Character#reload to get the latest from the doc object to the character and Character#reload! to reload the doc from the database and reload the character then
|
27
|
+
#def add_character_object(obj)
|
28
|
+
# @character_objects << obj
|
29
|
+
#end
|
30
|
+
|
31
|
+
# we don't do this. there is no proper way to update all given characters
|
32
|
+
# one must not rely on a character properties after the doc has been manipulated
|
33
|
+
# use Character#reload to get the latest from the doc object to the character and Character#reload! to reload the doc from the database and reload the character then
|
34
|
+
#def reload_character_objects()
|
35
|
+
# @just_reloaded = []
|
36
|
+
# @character_objects.each do |character|
|
37
|
+
# unless @just_reloaded.include?(character)
|
38
|
+
# @just_reloaded << character
|
39
|
+
# character.reload
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#end
|
43
|
+
|
22
44
|
def save_all()
|
23
45
|
refresh true
|
24
46
|
@save.each { |character_instance| character_instance.save }
|
@@ -15,6 +15,14 @@ class ThingTank
|
|
15
15
|
@dependencies
|
16
16
|
end
|
17
17
|
|
18
|
+
# we don't do this. there is no proper way to update all given characters
|
19
|
+
# one must not rely on a character properties after the doc has been manipulated
|
20
|
+
# use Character#reload to get the latest from the doc object to the character and Character#reload! to reload the doc from the database and reload the character then
|
21
|
+
#def reload
|
22
|
+
# super
|
23
|
+
# @dependencies.reload_character_objects()
|
24
|
+
#end
|
25
|
+
|
18
26
|
def first(key)
|
19
27
|
[self[key.to_s]].flatten.last
|
20
28
|
end
|
data/test/test_fakebase.rb
CHANGED
@@ -384,5 +384,21 @@ describe "should character a CouchRest::Database" do
|
|
384
384
|
assert_equal 'A1sub1', doc["check"]["sub"]["checker1"]
|
385
385
|
end
|
386
386
|
|
387
|
-
|
387
|
+
it "should not save the doc when saving a character, but flush its changes to the doc" do
|
388
|
+
doc = create :test => 'hiho'
|
389
|
+
doc['test'] = 'hoho'
|
390
|
+
|
391
|
+
character = doc.add_character(Check)
|
392
|
+
|
393
|
+
character.a = 'A'
|
388
394
|
|
395
|
+
assert_equal nil, doc['a']
|
396
|
+
assert_equal doc, character._doc
|
397
|
+
character.to_doc
|
398
|
+
assert_equal 'A', doc['a']
|
399
|
+
assert_equal 'hoho', doc['test']
|
400
|
+
assert_equal 'hiho', db_load(doc.id)['test']
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thingtank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-16 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &18368020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *18368020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: couchrest
|
27
|
-
requirement: &
|
27
|
+
requirement: &18366960 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *18366960
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: couchrest_model
|
38
|
-
requirement: &
|
38
|
+
requirement: &18364340 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *18364340
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: defined
|
49
|
-
requirement: &
|
49
|
+
requirement: &18363040 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *18363040
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: guard
|
60
|
-
requirement: &
|
60
|
+
requirement: &18362480 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *18362480
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: libnotify
|
71
|
-
requirement: &
|
71
|
+
requirement: &18361800 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *18361800
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rb-inotify
|
82
|
-
requirement: &
|
82
|
+
requirement: &18360960 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *18360960
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: guard-minitest
|
93
|
-
requirement: &
|
93
|
+
requirement: &18360160 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *18360160
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: linecache19
|
104
|
-
requirement: &
|
104
|
+
requirement: &18359500 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *18359500
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: ruby-debug19
|
115
|
-
requirement: &
|
115
|
+
requirement: &18358760 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ! '>='
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: '0'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *18358760
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: yard
|
126
|
-
requirement: &
|
126
|
+
requirement: &18357820 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,10 +131,10 @@ dependencies:
|
|
131
131
|
version: 0.6.0
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *18357820
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: bundler
|
137
|
-
requirement: &
|
137
|
+
requirement: &18357260 !ruby/object:Gem::Requirement
|
138
138
|
none: false
|
139
139
|
requirements:
|
140
140
|
- - ~>
|
@@ -142,10 +142,10 @@ dependencies:
|
|
142
142
|
version: 1.0.0
|
143
143
|
type: :development
|
144
144
|
prerelease: false
|
145
|
-
version_requirements: *
|
145
|
+
version_requirements: *18357260
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: jeweler
|
148
|
-
requirement: &
|
148
|
+
requirement: &18354200 !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
@@ -153,7 +153,7 @@ dependencies:
|
|
153
153
|
version: 1.6.4
|
154
154
|
type: :development
|
155
155
|
prerelease: false
|
156
|
-
version_requirements: *
|
156
|
+
version_requirements: *18354200
|
157
157
|
description:
|
158
158
|
email: ! 'Base64.decode64(bGludXhAbWFyY3JlbmVhcm5zLmRl
|
159
159
|
|
@@ -215,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
215
|
version: '0'
|
216
216
|
segments:
|
217
217
|
- 0
|
218
|
-
hash:
|
218
|
+
hash: -1916048387609429513
|
219
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
220
|
none: false
|
221
221
|
requirements:
|