dao 4.2.1 → 4.4.2
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 +103 -63
- data/Rakefile +3 -3
- data/dao.gemspec +27 -16
- data/lib/dao.rb +17 -17
- data/lib/dao/active_record.rb +1 -0
- data/lib/dao/api.rb +2 -1
- data/lib/dao/api/{endpoints.rb → call.rb} +1 -0
- data/lib/dao/api/context.rb +2 -0
- data/lib/dao/api/dsl.rb +1 -0
- data/lib/dao/api/initializers.rb +1 -0
- data/lib/dao/api/modes.rb +1 -0
- data/lib/dao/api/routes.rb +1 -0
- data/lib/dao/blankslate.rb +1 -0
- data/lib/dao/conducer.rb +315 -274
- data/lib/dao/conducer/active_model.rb +98 -0
- data/lib/dao/conducer/attributes.rb +1 -0
- data/lib/dao/conducer/autocrud.rb +58 -0
- data/lib/dao/conducer/callback_support.rb +20 -0
- data/lib/dao/conducer/collection.rb +45 -0
- data/lib/dao/conducer/controller_support.rb +104 -0
- data/lib/dao/conducer/nav_support.rb +9 -0
- data/lib/dao/conducer/view_support.rb +16 -0
- data/lib/dao/data.rb +2 -1
- data/lib/dao/db.rb +2 -0
- data/lib/dao/endpoint.rb +1 -0
- data/lib/dao/engine.rb +1 -0
- data/lib/dao/errors.rb +109 -99
- data/lib/dao/exceptions.rb +1 -0
- data/lib/dao/extractor.rb +1 -0
- data/lib/dao/form.rb +175 -20
- data/lib/dao/instance_exec.rb +1 -0
- data/lib/dao/mode.rb +1 -0
- data/lib/dao/mongo_mapper.rb +1 -0
- data/lib/dao/name.rb +1 -0
- data/lib/dao/params.rb +2 -1
- data/lib/dao/path.rb +1 -0
- data/lib/dao/path_map.rb +24 -0
- data/lib/dao/rack.rb +1 -0
- data/lib/dao/rack/middleware.rb +1 -0
- data/lib/dao/rack/middleware/params_parser.rb +1 -0
- data/lib/dao/rails.rb +12 -32
- data/lib/dao/rails/lib/generators/dao/USAGE +2 -2
- data/lib/dao/rails/lib/generators/dao/dao_generator.rb +8 -27
- data/lib/dao/rails/lib/generators/dao/templates/api.rb +2 -1
- data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +22 -20
- data/lib/dao/rails/lib/generators/dao/templates/conducer.rb +49 -43
- data/lib/dao/rails/lib/generators/dao/templates/dao.css +26 -25
- data/lib/dao/rails/lib/generators/dao/templates/dao.js +3 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +58 -45
- data/lib/dao/result.rb +50 -1
- data/lib/dao/route.rb +1 -0
- data/lib/dao/slug.rb +12 -36
- data/lib/dao/status.rb +91 -7
- data/lib/dao/stdext.rb +1 -0
- data/lib/dao/support.rb +90 -80
- data/lib/dao/upload.rb +396 -0
- data/lib/dao/validations.rb +23 -5
- data/lib/dao/validations/callback.rb +5 -0
- data/lib/dao/validations/common.rb +100 -3
- data/lib/dao/validations/instance.rb +17 -0
- data/lib/dao/validations/validator.rb +192 -91
- data/test/active_model_conducer_lint_test.rb +1 -0
- data/test/api_test.rb +15 -0
- data/test/conducer_test.rb +608 -90
- data/test/data/han-solo.jpg +0 -0
- data/test/form_test.rb +1 -0
- data/test/helper.rb +1 -0
- data/test/leak.rb +1 -0
- data/test/support_test.rb +4 -1
- data/test/testing.rb +1 -0
- data/test/validations_test.rb +176 -30
- metadata +120 -131
- data/b.rb +0 -38
- data/lib/dao/conducer/crud.rb +0 -70
- data/lib/dao/current.rb +0 -66
- data/lib/dao/image_cache.rb +0 -193
- data/lib/dao/rails/lib/generators/dao/templates/conducer_controller.rb +0 -79
- data/test/db.yml +0 -9
data/lib/dao/exceptions.rb
CHANGED
data/lib/dao/extractor.rb
CHANGED
data/lib/dao/form.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module Dao
|
2
3
|
class Form
|
3
4
|
# for html generation
|
@@ -8,6 +9,14 @@ module Dao
|
|
8
9
|
include Tagz.globally
|
9
10
|
end
|
10
11
|
|
12
|
+
# builder stuff for compatibity with rails' form_for()
|
13
|
+
#
|
14
|
+
class Builder
|
15
|
+
def Builder.new(object_name, object, view, options, block)
|
16
|
+
form = Form.new(object)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
11
20
|
# class methods
|
12
21
|
#
|
13
22
|
class << Form
|
@@ -144,18 +153,18 @@ module Dao
|
|
144
153
|
options = args.extract_options!.to_options!
|
145
154
|
keys = args.flatten
|
146
155
|
|
147
|
-
id = options.delete(:id) || id_for(keys)
|
148
|
-
klass = class_for(keys, options.delete(:class))
|
149
|
-
error = error_for(keys, options.delete(:error))
|
150
|
-
target = options.delete(:for) || id_for(keys)
|
151
|
-
|
152
156
|
content =
|
153
|
-
if block.nil?
|
154
|
-
titleize(
|
157
|
+
if block.nil?
|
158
|
+
keys.map{|key| key.to_s.titleize}.join(' ')
|
155
159
|
else
|
156
|
-
block ? block.call() : options.delete(:content)
|
160
|
+
block ? block.call() : (options.delete(:content) || options.delete(:value))
|
157
161
|
end
|
158
162
|
|
163
|
+
id = options.delete(:id) || id_for(keys + [:label])
|
164
|
+
klass = class_for(keys, options.delete(:class))
|
165
|
+
error = error_for(keys, options.delete(:error))
|
166
|
+
target = options.delete(:for) || id_for(keys)
|
167
|
+
|
159
168
|
label_(options_for(options, :for => target, :class => klass, :id => id, :data_error => error)){ content }
|
160
169
|
end
|
161
170
|
|
@@ -191,7 +200,7 @@ module Dao
|
|
191
200
|
input_(options_for(options)){}
|
192
201
|
end
|
193
202
|
|
194
|
-
def button(*args)
|
203
|
+
def button(*args, &block)
|
195
204
|
options = args.extract_options!.to_options!
|
196
205
|
keys = args.flatten
|
197
206
|
|
@@ -211,6 +220,91 @@ module Dao
|
|
211
220
|
button_(options_for(options, :type => type, :name => name, :value => value, :class => klass, :id => id, :data_error => error)){}
|
212
221
|
end
|
213
222
|
|
223
|
+
def radio_button(*args, &block)
|
224
|
+
options = args.extract_options!.to_options!
|
225
|
+
keys = args.flatten
|
226
|
+
|
227
|
+
type = options.delete(:type) || :radio
|
228
|
+
name = options.delete(:name) || name_for(keys)
|
229
|
+
id = options.delete(:id) || id_for(keys)
|
230
|
+
klass = class_for(keys, options.delete(:class))
|
231
|
+
error = error_for(keys, options.delete(:error))
|
232
|
+
|
233
|
+
unless options.has_key?(:checked)
|
234
|
+
checked =
|
235
|
+
if options.has_key?(:value) and attributes.has?(keys)
|
236
|
+
a = attributes.get(keys)
|
237
|
+
b = options[:value]
|
238
|
+
a==b or a.to_s==b.to_s
|
239
|
+
else
|
240
|
+
false
|
241
|
+
end
|
242
|
+
options[:checked] = checked if checked
|
243
|
+
end
|
244
|
+
|
245
|
+
input_(options_for(options, :type => :radio, :name => name, :class => klass, :id => id, :data_error => error)){}
|
246
|
+
end
|
247
|
+
|
248
|
+
def checkbox(*args, &block)
|
249
|
+
options = args.extract_options!.to_options!
|
250
|
+
keys = args.flatten
|
251
|
+
|
252
|
+
type = options.delete(:type) || :checkbox
|
253
|
+
name = options.delete(:name) || name_for(keys)
|
254
|
+
id = options.delete(:id) || id_for(keys)
|
255
|
+
klass = class_for(keys, options.delete(:class))
|
256
|
+
error = error_for(keys, options.delete(:error))
|
257
|
+
values = options.delete(:values) || options.delete(:checked)
|
258
|
+
|
259
|
+
unless options.has_key?(:checked)
|
260
|
+
checked = !!attributes.get(keys)
|
261
|
+
options[:checked] = checked if checked
|
262
|
+
end
|
263
|
+
|
264
|
+
value_for =
|
265
|
+
case values
|
266
|
+
when false, nil
|
267
|
+
{true => '1', false => '0'}
|
268
|
+
when Hash
|
269
|
+
h = {}
|
270
|
+
values.map{|k, v| h[ k =~ /t|1|on|yes/ ? true : false ] = v}
|
271
|
+
h
|
272
|
+
else
|
273
|
+
t, f, *ignored = Array(values).flatten.compact
|
274
|
+
{true => t, false => f}
|
275
|
+
end
|
276
|
+
value_for[true] ||= '1'
|
277
|
+
value_for[false] ||= '0'
|
278
|
+
|
279
|
+
hidden_options =
|
280
|
+
options.dup.tap{|o| o.delete(:checked)}
|
281
|
+
|
282
|
+
tagz{
|
283
|
+
input_(options_for(hidden_options, :type => :hidden, :name => name, :value => value_for[false])){}
|
284
|
+
|
285
|
+
__
|
286
|
+
|
287
|
+
input_(
|
288
|
+
options_for(
|
289
|
+
options,
|
290
|
+
:type => :checkbox,
|
291
|
+
:name => name,
|
292
|
+
:value => value_for[true],
|
293
|
+
:class => klass,
|
294
|
+
:id => id,
|
295
|
+
:data_error => error
|
296
|
+
)
|
297
|
+
){}
|
298
|
+
}
|
299
|
+
end
|
300
|
+
|
301
|
+
def hidden(*args, &block)
|
302
|
+
options = args.extract_options!.to_options!
|
303
|
+
options[:type] = :hidden
|
304
|
+
args.push(options)
|
305
|
+
input(*args, &block)
|
306
|
+
end
|
307
|
+
|
214
308
|
def reset(*args)
|
215
309
|
options = args.extract_options!.to_options!
|
216
310
|
options[:type] = :reset
|
@@ -242,7 +336,7 @@ module Dao
|
|
242
336
|
keys = args.flatten
|
243
337
|
|
244
338
|
name = options.delete(:name) || name_for(keys)
|
245
|
-
from = options.delete(:from) || options.delete(:options)
|
339
|
+
from = options.delete(:from) || options.delete(:options)
|
246
340
|
blank = options.delete(:blank)
|
247
341
|
|
248
342
|
selected =
|
@@ -301,17 +395,19 @@ module Dao
|
|
301
395
|
|
302
396
|
case returned
|
303
397
|
when Array
|
304
|
-
|
398
|
+
content, value, selected, *ignored = returned
|
305
399
|
when Hash
|
400
|
+
content = returned[:content]
|
306
401
|
value = returned[:value]
|
307
|
-
content = returned[:content] || value
|
308
402
|
selected = returned[:selected]
|
309
403
|
else
|
310
|
-
value = returned
|
311
404
|
content = returned
|
405
|
+
value = returned
|
312
406
|
selected = nil
|
313
407
|
end
|
314
408
|
|
409
|
+
value ||= content
|
410
|
+
|
315
411
|
if selected.nil?
|
316
412
|
selected = value.to_s==selected_value.to_s
|
317
413
|
end
|
@@ -323,6 +419,31 @@ module Dao
|
|
323
419
|
}
|
324
420
|
end
|
325
421
|
|
422
|
+
def upload(*args, &block)
|
423
|
+
options = args.extract_options!.to_options!
|
424
|
+
keys = args.flatten
|
425
|
+
|
426
|
+
cache_key = keys + [:cache]
|
427
|
+
file_key = keys + [:file]
|
428
|
+
|
429
|
+
cache_name = options.delete(:cache_name) || name_for(cache_key)
|
430
|
+
file_name = options.delete(:file_name) || options.delete(:name) || name_for(file_key)
|
431
|
+
|
432
|
+
id = options.delete(:id) || id_for(keys)
|
433
|
+
klass = class_for(keys, options.delete(:class))
|
434
|
+
error = error_for(keys, options.delete(:error))
|
435
|
+
|
436
|
+
cache_value = attributes.get(cache_key)
|
437
|
+
|
438
|
+
tagz{
|
439
|
+
input_(:name => cache_name, :value => cache_value, :type => :hidden){ }
|
440
|
+
|
441
|
+
__
|
442
|
+
|
443
|
+
input_(options_for(options, :name => file_name, :class => klass, :id => id, :data_error => error, :type => :file)){ }
|
444
|
+
}
|
445
|
+
end
|
446
|
+
|
326
447
|
# html generation support methods
|
327
448
|
#
|
328
449
|
def id_for(keys)
|
@@ -366,11 +487,32 @@ module Dao
|
|
366
487
|
else
|
367
488
|
value
|
368
489
|
end
|
369
|
-
Tagz.escapeHTML(value)
|
490
|
+
value.respond_to?(:html_safe) ? value : Tagz.escapeHTML(value)
|
491
|
+
end
|
492
|
+
|
493
|
+
def Form.prefix_for(name)
|
494
|
+
"dao[#{ name }]"
|
370
495
|
end
|
371
496
|
|
372
497
|
def Form.name_for(name, *keys)
|
373
|
-
"
|
498
|
+
"#{ prefix_for(name) }[#{ key_for(*keys) }]"
|
499
|
+
end
|
500
|
+
|
501
|
+
def Form.key_for(*keys)
|
502
|
+
keys.flatten.compact.map do |key|
|
503
|
+
case
|
504
|
+
when Integer === key
|
505
|
+
key
|
506
|
+
when key =~ /^\d+$/
|
507
|
+
"~#{ key }"
|
508
|
+
else
|
509
|
+
key
|
510
|
+
end
|
511
|
+
end.join('.')
|
512
|
+
end
|
513
|
+
|
514
|
+
def key_for(*keys)
|
515
|
+
Form.key_for(name, *keys)
|
374
516
|
end
|
375
517
|
|
376
518
|
def name_for(*keys)
|
@@ -380,11 +522,28 @@ module Dao
|
|
380
522
|
def options_for(*hashes)
|
381
523
|
map = Map.new
|
382
524
|
hashes.flatten.each do |h|
|
383
|
-
h.
|
525
|
+
case((data = h.delete(:data) || h.delete('data')))
|
526
|
+
when Hash
|
527
|
+
data.each{|k,v| map[data_attr_for(k)] = v unless v.nil?}
|
528
|
+
else
|
529
|
+
h[:data] = data
|
530
|
+
end
|
531
|
+
|
532
|
+
h.each do |k,v|
|
533
|
+
map[attr_for(k)] = v unless v.nil?
|
534
|
+
end
|
384
535
|
end
|
385
536
|
map
|
386
537
|
end
|
387
538
|
|
539
|
+
def attr_for(string)
|
540
|
+
slug_for(string).gsub(/_/, '-')
|
541
|
+
end
|
542
|
+
|
543
|
+
def data_attr_for(string)
|
544
|
+
"data-#{ attr_for(string) }"
|
545
|
+
end
|
546
|
+
|
388
547
|
def slug_for(string)
|
389
548
|
string = string.to_s
|
390
549
|
words = string.to_s.scan(%r/\w+/)
|
@@ -393,10 +552,6 @@ module Dao
|
|
393
552
|
words.join('-').downcase.sub(/_+$/, '')
|
394
553
|
end
|
395
554
|
|
396
|
-
def attr_for(string)
|
397
|
-
slug_for(string).gsub(/_/, '-')
|
398
|
-
end
|
399
|
-
|
400
555
|
def titleize(string)
|
401
556
|
string = string.to_s
|
402
557
|
string = string.titleize if string.respond_to?(:titleize)
|
data/lib/dao/instance_exec.rb
CHANGED
data/lib/dao/mode.rb
CHANGED
data/lib/dao/mongo_mapper.rb
CHANGED
data/lib/dao/name.rb
CHANGED
data/lib/dao/params.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module Dao
|
2
3
|
class Params < ::Map
|
3
4
|
# mixins
|
@@ -36,7 +37,7 @@ module Dao
|
|
36
37
|
# look good for inspect
|
37
38
|
#
|
38
39
|
def inspect
|
39
|
-
|
40
|
+
Dao.json_for(self)
|
40
41
|
end
|
41
42
|
|
42
43
|
# support updates with dao-ish objects
|
data/lib/dao/path.rb
CHANGED
data/lib/dao/path_map.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Dao
|
3
|
+
class PathMap < ::Map
|
4
|
+
def to_json(*args, &block)
|
5
|
+
as_json.to_json(*args, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def as_json
|
9
|
+
inject(Map.new){|json, kv| json.update(json_key_for(kv.first) => kv.last)}
|
10
|
+
end
|
11
|
+
|
12
|
+
def json_key_for(key)
|
13
|
+
Array(key).join('.').gsub(/\.(\d+)(\.)?/, '[\1]\2')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
if $0 == __FILE__
|
20
|
+
pm = Dao::PathMap.new
|
21
|
+
pm[[:array, 0, :key]] = 'value'
|
22
|
+
pm[[:key]] = 'value'
|
23
|
+
p pm.as_json
|
24
|
+
end
|
data/lib/dao/rack.rb
CHANGED
data/lib/dao/rack/middleware.rb
CHANGED
data/lib/dao/rails.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
if defined?(Rails)
|
2
3
|
|
3
4
|
module Dao
|
4
5
|
## support unloadable
|
5
6
|
#
|
6
|
-
def Api.before_remove_const
|
7
|
-
unload!
|
8
|
-
end
|
7
|
+
#def Api.before_remove_const
|
8
|
+
#unload!
|
9
|
+
#end
|
9
10
|
|
10
11
|
##
|
11
12
|
#
|
@@ -17,8 +18,7 @@ if defined?(Rails)
|
|
17
18
|
|
18
19
|
paths.path = ROOT_DIR
|
19
20
|
|
20
|
-
config.autoload_paths += %w( app/models app )
|
21
|
-
|
21
|
+
### config.autoload_paths += %w( app/models app )
|
22
22
|
### config.autoload_paths << APP_DIR
|
23
23
|
### $LOAD_PATH.push(File.join(Rails.root.to_s, 'app'))
|
24
24
|
|
@@ -30,39 +30,19 @@ if defined?(Rails)
|
|
30
30
|
|
31
31
|
# yes yes, this should probably be somewhere else...
|
32
32
|
#
|
33
|
-
config.
|
33
|
+
config.before_initialize do
|
34
34
|
|
35
35
|
ActionController::Base.module_eval do
|
36
|
-
|
37
|
-
before_filter do |controller|
|
38
|
-
# set the dao controller
|
39
|
-
#
|
40
|
-
Dao.current_controller = controller
|
41
|
-
|
42
|
-
# pre-parse any obvious dao params
|
43
|
-
#
|
44
|
-
controller.instance_eval do
|
45
|
-
Dao.normalize_parameters(params)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# you will likely want to override this!
|
36
|
+
# normalize dao params
|
50
37
|
#
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
%w( real_user effective_user current_user ).each do |attr|
|
55
|
-
getter, setter = "#{ attr }", "#{ attr }="
|
56
|
-
api.send(setter, send(getter)) if(respond_to?(getter) and api.respond_to?(setter))
|
57
|
-
end
|
58
|
-
api
|
59
|
-
)
|
38
|
+
before_filter do |controller|
|
39
|
+
Dao.current_controller ||= controller
|
40
|
+
Dao.normalize_parameters(controller.send(:params))
|
60
41
|
end
|
61
|
-
helper_method(:current_api)
|
62
|
-
alias_method(:api, :current_api)
|
63
|
-
helper_method(:api)
|
64
42
|
|
65
43
|
# setup sane rescuing from dao errors with crap statuses
|
44
|
+
#
|
45
|
+
# raise(Dao::Error::Result.new(result))
|
66
46
|
#
|
67
47
|
rescue_from(Dao::Error::Result) do |error|
|
68
48
|
result = error.result
|