dao 4.4.4 → 4.6.4
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.
- data/README +2 -0
- data/dao.gemspec +9 -6
- data/lib/dao.rb +20 -11
- data/lib/dao/api/call.rb +1 -1
- data/lib/dao/conducer.rb +152 -106
- data/lib/dao/conducer/active_model.rb +8 -1
- data/lib/dao/conducer/collection.rb +4 -0
- data/lib/dao/conducer/controller_support.rb +8 -4
- data/lib/dao/conducer/nav_support.rb +2 -1
- data/lib/dao/conducer/view_support.rb +8 -4
- data/lib/dao/errors.rb +114 -48
- data/lib/dao/form.rb +113 -91
- data/lib/dao/rails.rb +4 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.css +11 -21
- data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +17 -43
- data/lib/dao/route.rb +4 -3
- data/lib/dao/upload.rb +27 -5
- data/lib/dao/validations.rb +0 -1
- data/lib/dao/validations/validator.rb +5 -1
- data/test/conducer_test.rb +56 -9
- data/test/errors_test.rb +81 -0
- data/test/form_test.rb +123 -0
- data/test/helper.rb +11 -0
- data/test/support_test.rb +0 -1
- data/test/validations_test.rb +29 -8
- metadata +96 -28
data/README
CHANGED
@@ -146,6 +146,7 @@ READING
|
|
146
146
|
http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
|
147
147
|
http://google-styleguide.googlecode.com/svn/trunk/jsoncstyleguide.xml
|
148
148
|
http://pragdave.blogs.pragprog.com/pragdave/2007/03/the_radar_archi.html
|
149
|
+
http://borisstaal.com/post/22586260753/mvc-in-a-browser-vs-reality
|
149
150
|
|
150
151
|
|
151
152
|
INSTALL
|
@@ -161,3 +162,4 @@ HISTORY
|
|
161
162
|
- drop custom form encoding. just use a rack-like approach.
|
162
163
|
- dao form parameter encoding has changed slightly to 'dao[/api/path][x,y,z]=42'
|
163
164
|
- dao form paramters are now preparsed in a before filter
|
165
|
+
|
data/dao.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
Gem::Specification::new do |spec|
|
5
5
|
spec.name = "dao"
|
6
|
-
spec.version = "4.
|
6
|
+
spec.version = "4.6.4"
|
7
7
|
spec.platform = Gem::Platform::RUBY
|
8
8
|
spec.summary = "dao"
|
9
9
|
spec.description = "description: dao kicks the ass"
|
@@ -88,6 +88,7 @@ Gem::Specification::new do |spec|
|
|
88
88
|
"test/conducer_test.rb",
|
89
89
|
"test/data",
|
90
90
|
"test/data/han-solo.jpg",
|
91
|
+
"test/errors_test.rb",
|
91
92
|
"test/form_test.rb",
|
92
93
|
"test/helper.rb",
|
93
94
|
"test/leak.rb",
|
@@ -104,11 +105,13 @@ Gem::Specification::new do |spec|
|
|
104
105
|
|
105
106
|
spec.add_dependency(*["rails", " >= 3.1"])
|
106
107
|
|
107
|
-
spec.add_dependency(*["map", " >=
|
108
|
+
spec.add_dependency(*["map", " >= 6.0.0"])
|
108
109
|
|
109
110
|
spec.add_dependency(*["fattr", " >= 2.2"])
|
110
111
|
|
111
|
-
spec.add_dependency(*["
|
112
|
+
spec.add_dependency(*["coerce", " >= 0.0.3"])
|
113
|
+
|
114
|
+
spec.add_dependency(*["tagz", " >= 9.6"])
|
112
115
|
|
113
116
|
spec.add_dependency(*["multi_json", " >= 1.0.3"])
|
114
117
|
|
@@ -116,11 +119,11 @@ Gem::Specification::new do |spec|
|
|
116
119
|
|
117
120
|
spec.add_dependency(*["wrap", " >= 1.5.0"])
|
118
121
|
|
119
|
-
spec.add_dependency(*["rails_current", " >= 1.
|
122
|
+
spec.add_dependency(*["rails_current", " >= 1.7.0"])
|
120
123
|
|
121
|
-
spec.add_dependency(*["rails_nav", " >= 1.
|
124
|
+
spec.add_dependency(*["rails_nav", " >= 1.3.0"])
|
122
125
|
|
123
|
-
spec.add_dependency(*["
|
126
|
+
spec.add_dependency(*["rails_errors2html", " >= 1.3.0"])
|
124
127
|
|
125
128
|
|
126
129
|
spec.extensions.push(*[])
|
data/lib/dao.rb
CHANGED
@@ -6,11 +6,12 @@
|
|
6
6
|
require 'fileutils'
|
7
7
|
require 'cgi'
|
8
8
|
require 'tmpdir'
|
9
|
+
require 'yaml'
|
9
10
|
|
10
11
|
# dao libs
|
11
12
|
#
|
12
13
|
module Dao
|
13
|
-
Version = '4.
|
14
|
+
Version = '4.6.4' unless defined?(Version)
|
14
15
|
|
15
16
|
def version
|
16
17
|
Dao::Version
|
@@ -18,16 +19,17 @@
|
|
18
19
|
|
19
20
|
def dependencies
|
20
21
|
{
|
21
|
-
'rails'
|
22
|
-
'map'
|
23
|
-
'fattr'
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'
|
28
|
-
'
|
29
|
-
'
|
30
|
-
'
|
22
|
+
'rails' => [ 'rails' , ' >= 3.1' ] ,
|
23
|
+
'map' => [ 'map' , ' >= 6.0.0' ] ,
|
24
|
+
'fattr' => [ 'fattr' , ' >= 2.2' ] ,
|
25
|
+
'coerce' => [ 'coerce' , ' >= 0.0.3' ] ,
|
26
|
+
'tagz' => [ 'tagz' , ' >= 9.6' ] ,
|
27
|
+
'multi_json' => [ 'multi_json' , ' >= 1.0.3' ] ,
|
28
|
+
'uuidtools' => [ 'uuidtools' , ' >= 2.1.2' ] ,
|
29
|
+
'wrap' => [ 'wrap' , ' >= 1.5.0' ] ,
|
30
|
+
'rails_current' => [ 'rails_current' , ' >= 1.7.0' ] ,
|
31
|
+
'rails_nav' => [ 'rails_nav' , ' >= 1.3.0' ] ,
|
32
|
+
'rails_errors2html' => [ 'rails_errors2html' , ' >= 1.3.0' ] ,
|
31
33
|
}
|
32
34
|
end
|
33
35
|
|
@@ -115,6 +117,13 @@
|
|
115
117
|
upload.rb
|
116
118
|
]
|
117
119
|
|
120
|
+
|
121
|
+
unless defined?(::UUIDTools::Config)
|
122
|
+
::UUIDTools.module_eval do
|
123
|
+
Config = ::RbConfig # shuts up warnings...
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
118
127
|
# protect against rails' too clever reloading
|
119
128
|
#
|
120
129
|
=begin
|
data/lib/dao/api/call.rb
CHANGED
data/lib/dao/conducer.rb
CHANGED
@@ -65,90 +65,134 @@ module Dao
|
|
65
65
|
raise Error.new(*args, &block)
|
66
66
|
end
|
67
67
|
end
|
68
|
-
end
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
allocate.tap do |conducer|
|
74
|
-
action = Action.new(action, conducer)
|
75
|
-
Dao.call(conducer, :init, action, *args, &block)
|
76
|
-
Dao.call(conducer, :initialize, *args, &block)
|
69
|
+
def conduces?(model)
|
70
|
+
model_class = model.is_a?(Class) ? model : model.class
|
71
|
+
model_class.model_name == (self.conduces || self).model_name
|
77
72
|
end
|
78
|
-
end
|
79
73
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
%w( new create edit update destroy ).each do |action|
|
85
|
-
module_eval <<-__, __FILE__, __LINE__
|
86
|
-
def Conducer.for_#{ action }(*args, &block)
|
87
|
-
Conducer.for(#{ action.inspect }, *args, &block)
|
74
|
+
def conduces(*args)
|
75
|
+
unless args.blank?
|
76
|
+
@conduces = args.shift
|
77
|
+
raise(ArgumentError, @conduces.inspect) unless @conduces.respond_to?(:model_name)
|
88
78
|
end
|
89
|
-
|
90
|
-
|
79
|
+
@conduces ||= nil
|
80
|
+
end
|
91
81
|
|
92
|
-
|
93
|
-
|
94
|
-
def Conducer.new(*args, &block)
|
95
|
-
allocate.tap do |conducer|
|
96
|
-
Dao.call(conducer, :init, *args, &block)
|
97
|
-
Dao.call(conducer, :initialize, *args, &block)
|
82
|
+
def conduces=(model)
|
83
|
+
conduces(model)
|
98
84
|
end
|
99
85
|
end
|
100
86
|
|
87
|
+
# instance methods
|
88
|
+
#
|
101
89
|
%w[
|
102
|
-
name
|
103
90
|
attributes
|
104
91
|
form
|
105
92
|
params
|
106
93
|
errors
|
107
|
-
status
|
108
94
|
models
|
109
95
|
model
|
110
96
|
conduces
|
111
97
|
].each{|attr| fattr(attr)}
|
112
98
|
|
113
|
-
|
99
|
+
# ctors
|
114
100
|
#
|
115
|
-
def
|
101
|
+
def Conducer.new(*args, &block)
|
102
|
+
allocate.tap do |conducer|
|
103
|
+
args = Dao.call(conducer, :process_arguments, *args)
|
104
|
+
|
105
|
+
Dao.call(conducer, :before_initialize, *args, &block)
|
106
|
+
Dao.call(conducer, :initialize, *args, &block)
|
107
|
+
Dao.call(conducer, :after_initialize, *args, &block)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def Conducer.for(*args, &block)
|
112
|
+
action =
|
113
|
+
case args.first
|
114
|
+
when Action, Symbol, String
|
115
|
+
args.shift.to_s
|
116
|
+
else
|
117
|
+
controller.send(:action_name).to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
conducer = new(Action.new(action), *args, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def Conducer.call(*args, &block)
|
124
|
+
self.for(*args, &block)
|
125
|
+
end
|
126
|
+
|
127
|
+
%w( new create edit update destroy ).each do |action|
|
128
|
+
class_eval <<-__, __FILE__, __LINE__
|
129
|
+
def Conducer.for_#{ action }(*args, &block)
|
130
|
+
Conducer.for(#{ action.inspect }, *args, &block)
|
131
|
+
end
|
132
|
+
__
|
133
|
+
end
|
134
|
+
|
135
|
+
def process_arguments(*args)
|
116
136
|
controllers, args = args.partition{|arg| arg.is_a?(ActionController::Base)}
|
117
137
|
actions, args = args.partition{|arg| arg.is_a?(Action)}
|
138
|
+
|
139
|
+
controller = controllers.shift || Dao.current_controller || Dao.mock_controller
|
140
|
+
action = actions.shift
|
141
|
+
|
142
|
+
set_controller(controller) if controller
|
143
|
+
set_action(action) if action
|
144
|
+
|
145
|
+
args.map{|arg| arg.class == Hash ? Map.for(arg) : arg}
|
146
|
+
end
|
147
|
+
|
148
|
+
def before_initialize(*args, &block)
|
118
149
|
models, args = args.partition{|arg| arg.respond_to?(:persisted?) }
|
119
|
-
|
150
|
+
params, args = args.partition{|arg| arg.is_a?(Hash)}
|
120
151
|
|
121
|
-
@
|
152
|
+
@params = Map.new
|
122
153
|
@attributes = Attributes.for(self)
|
154
|
+
|
123
155
|
@form = Form.for(self)
|
124
|
-
@
|
156
|
+
@form.name = self.class.model_name.singular.sub(/_+$/, '')
|
125
157
|
|
126
158
|
@errors = validator.errors
|
127
|
-
@status = validator.status
|
128
|
-
|
129
|
-
set_controller(controllers.shift || Dao.current_controller || Dao.mock_controller)
|
130
|
-
|
131
|
-
set_action(actions.shift) unless actions.empty?
|
132
159
|
|
133
160
|
set_models(models)
|
134
161
|
|
135
162
|
set_mounts(self.class.mounted)
|
136
163
|
|
137
|
-
update_params(
|
164
|
+
update_params(*params) unless params.empty?
|
165
|
+
|
166
|
+
@initialize_overridden = true
|
167
|
+
end
|
168
|
+
|
169
|
+
def initialize(*args, &block)
|
170
|
+
@initialize_overridden = false
|
171
|
+
update_models(models) unless models.empty?
|
172
|
+
end
|
138
173
|
|
139
|
-
|
174
|
+
def after_initialize(*args, &block)
|
175
|
+
unless @initialize_overridden
|
176
|
+
initialize_for_action(*args, &block)
|
177
|
+
update_attributes(params) unless params.empty?
|
178
|
+
end
|
140
179
|
end
|
141
180
|
|
181
|
+
def initialize_for_action(*args, &block)
|
182
|
+
@action.call(:initialize, *args, &block)
|
183
|
+
end
|
184
|
+
|
185
|
+
#
|
142
186
|
def set_models(*models)
|
143
187
|
@models =
|
144
188
|
models.flatten.compact
|
145
189
|
|
146
190
|
candidates =
|
147
|
-
@models.select{|model| model
|
191
|
+
@models.select{|model| conduces?(model)}
|
148
192
|
|
149
193
|
@model =
|
150
|
-
case
|
151
|
-
when 1
|
194
|
+
case
|
195
|
+
when candidates.size == 1
|
152
196
|
candidates.first
|
153
197
|
else
|
154
198
|
@models.first
|
@@ -161,22 +205,13 @@ module Dao
|
|
161
205
|
end
|
162
206
|
end
|
163
207
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
def initialize(*args, &block)
|
172
|
-
initialize_for_action(*args, &block)
|
173
|
-
update_models(models) unless models.empty?
|
174
|
-
update_attributes(params) unless params.empty?
|
175
|
-
end
|
176
|
-
|
177
|
-
def set_mounts(list)
|
178
|
-
list.each do |args, block|
|
179
|
-
mount(*args, &block)
|
208
|
+
def update_models(*models)
|
209
|
+
models.flatten.compact.each do |model|
|
210
|
+
if conduces?(model)
|
211
|
+
update_attributes(model.attributes)
|
212
|
+
else
|
213
|
+
update_attributes(model_key_for(model), model.attributes)
|
214
|
+
end
|
180
215
|
end
|
181
216
|
end
|
182
217
|
|
@@ -189,10 +224,7 @@ module Dao
|
|
189
224
|
end.demodulize.underscore
|
190
225
|
end
|
191
226
|
|
192
|
-
|
193
|
-
@action.call(:initialize, *args, &block)
|
194
|
-
end
|
195
|
-
|
227
|
+
#
|
196
228
|
def conduces(*args)
|
197
229
|
if args.empty?
|
198
230
|
@model
|
@@ -210,19 +242,42 @@ module Dao
|
|
210
242
|
end
|
211
243
|
|
212
244
|
def conduces?(model)
|
213
|
-
|
245
|
+
if @model
|
246
|
+
@model == model
|
247
|
+
else
|
248
|
+
self.class.conduces?(model)
|
249
|
+
end
|
214
250
|
end
|
215
251
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
else
|
221
|
-
update_attributes(model_key_for(model), model.attributes)
|
222
|
-
end
|
252
|
+
#
|
253
|
+
def set_mounts(list)
|
254
|
+
list.each do |args, block|
|
255
|
+
mount(*args, &block)
|
223
256
|
end
|
224
257
|
end
|
225
258
|
|
259
|
+
def mount(object, *args, &block)
|
260
|
+
mounted = object.mount(self, *args, &block)
|
261
|
+
ensure
|
262
|
+
if mounted
|
263
|
+
Dao.ensure_interface!(mounted, :_set, :_key, :_value, :_clear)
|
264
|
+
self.mounted.push(mounted)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def mounted
|
269
|
+
@mounted ||= []
|
270
|
+
end
|
271
|
+
|
272
|
+
def self.mount(*args, &block)
|
273
|
+
mounted.push([args, block])
|
274
|
+
end
|
275
|
+
|
276
|
+
def self.mounted
|
277
|
+
@mounted ||= []
|
278
|
+
end
|
279
|
+
|
280
|
+
#
|
226
281
|
def update_attributes(*args, &block)
|
227
282
|
attributes =
|
228
283
|
case
|
@@ -238,7 +293,7 @@ module Dao
|
|
238
293
|
end
|
239
294
|
end
|
240
295
|
|
241
|
-
@attributes.
|
296
|
+
@attributes.add(attributes)
|
242
297
|
|
243
298
|
update_mounted_attributes!
|
244
299
|
|
@@ -250,6 +305,7 @@ module Dao
|
|
250
305
|
|
251
306
|
deepest_mounts_first.each do |mount|
|
252
307
|
value = @attributes.get(mount._key)
|
308
|
+
next if(value.nil? or value.object_id == mount.object_id)
|
253
309
|
mount._set(value) if mount.respond_to?(:_set)
|
254
310
|
@attributes.set(mount._key => mount)
|
255
311
|
end
|
@@ -310,7 +366,14 @@ module Dao
|
|
310
366
|
end
|
311
367
|
end
|
312
368
|
|
313
|
-
|
369
|
+
#
|
370
|
+
def update_params(*hashes)
|
371
|
+
hashes.flatten.compact.each do |hash|
|
372
|
+
@params.add(hash)
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
# id support
|
314
377
|
#
|
315
378
|
def id(*args)
|
316
379
|
if args.blank?
|
@@ -342,19 +405,19 @@ module Dao
|
|
342
405
|
object.respond_to?(:persisted?)
|
343
406
|
end
|
344
407
|
|
345
|
-
|
408
|
+
# mixin controller support
|
346
409
|
#
|
347
|
-
|
410
|
+
class_eval(&ControllerSupport)
|
348
411
|
|
349
|
-
|
412
|
+
# mixin callback support
|
350
413
|
#
|
351
|
-
|
414
|
+
class_eval(&CallbackSupport)
|
352
415
|
|
353
|
-
|
416
|
+
# mixin view support
|
354
417
|
#
|
355
|
-
|
418
|
+
class_eval(&ViewSupport)
|
356
419
|
|
357
|
-
|
420
|
+
# persistence
|
358
421
|
#
|
359
422
|
def save
|
360
423
|
default_save
|
@@ -408,29 +471,8 @@ module Dao
|
|
408
471
|
true
|
409
472
|
end
|
410
473
|
|
411
|
-
|
474
|
+
# misc
|
412
475
|
#
|
413
|
-
def mount(object, *args, &block)
|
414
|
-
mounted = object.mount(self, *args, &block)
|
415
|
-
ensure
|
416
|
-
if mounted
|
417
|
-
Dao.ensure_interface!(mounted, :_set, :_key, :_value, :_clear)
|
418
|
-
self.mounted.push(mounted)
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
def mounted
|
423
|
-
@mounted ||= []
|
424
|
-
end
|
425
|
-
|
426
|
-
def self.mount(*args, &block)
|
427
|
-
mounted.push([args, block])
|
428
|
-
end
|
429
|
-
|
430
|
-
def self.mounted
|
431
|
-
@mounted ||= []
|
432
|
-
end
|
433
|
-
|
434
476
|
def key_for(key)
|
435
477
|
Dao.key_for(key)
|
436
478
|
end
|
@@ -439,10 +481,6 @@ module Dao
|
|
439
481
|
validator.errors
|
440
482
|
end
|
441
483
|
|
442
|
-
def status
|
443
|
-
validator.status
|
444
|
-
end
|
445
|
-
|
446
484
|
def model_name
|
447
485
|
self.class.model_name
|
448
486
|
end
|
@@ -451,6 +489,10 @@ module Dao
|
|
451
489
|
@form
|
452
490
|
end
|
453
491
|
|
492
|
+
def form_builder
|
493
|
+
Form::Builder
|
494
|
+
end
|
495
|
+
|
454
496
|
def helper
|
455
497
|
@helper ||= ::Helper.new
|
456
498
|
end
|
@@ -468,11 +510,15 @@ module Dao
|
|
468
510
|
end
|
469
511
|
|
470
512
|
def inspect
|
471
|
-
"#{ self.class.name }(#{ @attributes.inspect.
|
513
|
+
"#{ self.class.name }(#{ @attributes.inspect.strip })"
|
472
514
|
end
|
473
515
|
|
474
516
|
def to_s
|
475
517
|
inspect
|
476
518
|
end
|
477
519
|
end
|
520
|
+
|
521
|
+
Resource = Conducer
|
522
|
+
Presenter = Conducer
|
523
|
+
Conductor = Conducer
|
478
524
|
end
|