dao 4.2.1 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/README +103 -63
  2. data/Rakefile +3 -3
  3. data/dao.gemspec +27 -16
  4. data/lib/dao.rb +17 -17
  5. data/lib/dao/active_record.rb +1 -0
  6. data/lib/dao/api.rb +2 -1
  7. data/lib/dao/api/{endpoints.rb → call.rb} +1 -0
  8. data/lib/dao/api/context.rb +2 -0
  9. data/lib/dao/api/dsl.rb +1 -0
  10. data/lib/dao/api/initializers.rb +1 -0
  11. data/lib/dao/api/modes.rb +1 -0
  12. data/lib/dao/api/routes.rb +1 -0
  13. data/lib/dao/blankslate.rb +1 -0
  14. data/lib/dao/conducer.rb +315 -274
  15. data/lib/dao/conducer/active_model.rb +98 -0
  16. data/lib/dao/conducer/attributes.rb +1 -0
  17. data/lib/dao/conducer/autocrud.rb +58 -0
  18. data/lib/dao/conducer/callback_support.rb +20 -0
  19. data/lib/dao/conducer/collection.rb +45 -0
  20. data/lib/dao/conducer/controller_support.rb +104 -0
  21. data/lib/dao/conducer/nav_support.rb +9 -0
  22. data/lib/dao/conducer/view_support.rb +16 -0
  23. data/lib/dao/data.rb +2 -1
  24. data/lib/dao/db.rb +2 -0
  25. data/lib/dao/endpoint.rb +1 -0
  26. data/lib/dao/engine.rb +1 -0
  27. data/lib/dao/errors.rb +109 -99
  28. data/lib/dao/exceptions.rb +1 -0
  29. data/lib/dao/extractor.rb +1 -0
  30. data/lib/dao/form.rb +175 -20
  31. data/lib/dao/instance_exec.rb +1 -0
  32. data/lib/dao/mode.rb +1 -0
  33. data/lib/dao/mongo_mapper.rb +1 -0
  34. data/lib/dao/name.rb +1 -0
  35. data/lib/dao/params.rb +2 -1
  36. data/lib/dao/path.rb +1 -0
  37. data/lib/dao/path_map.rb +24 -0
  38. data/lib/dao/rack.rb +1 -0
  39. data/lib/dao/rack/middleware.rb +1 -0
  40. data/lib/dao/rack/middleware/params_parser.rb +1 -0
  41. data/lib/dao/rails.rb +12 -32
  42. data/lib/dao/rails/lib/generators/dao/USAGE +2 -2
  43. data/lib/dao/rails/lib/generators/dao/dao_generator.rb +8 -27
  44. data/lib/dao/rails/lib/generators/dao/templates/api.rb +2 -1
  45. data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +22 -20
  46. data/lib/dao/rails/lib/generators/dao/templates/conducer.rb +49 -43
  47. data/lib/dao/rails/lib/generators/dao/templates/dao.css +26 -25
  48. data/lib/dao/rails/lib/generators/dao/templates/dao.js +3 -0
  49. data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +58 -45
  50. data/lib/dao/result.rb +50 -1
  51. data/lib/dao/route.rb +1 -0
  52. data/lib/dao/slug.rb +12 -36
  53. data/lib/dao/status.rb +91 -7
  54. data/lib/dao/stdext.rb +1 -0
  55. data/lib/dao/support.rb +90 -80
  56. data/lib/dao/upload.rb +396 -0
  57. data/lib/dao/validations.rb +23 -5
  58. data/lib/dao/validations/callback.rb +5 -0
  59. data/lib/dao/validations/common.rb +100 -3
  60. data/lib/dao/validations/instance.rb +17 -0
  61. data/lib/dao/validations/validator.rb +192 -91
  62. data/test/active_model_conducer_lint_test.rb +1 -0
  63. data/test/api_test.rb +15 -0
  64. data/test/conducer_test.rb +608 -90
  65. data/test/data/han-solo.jpg +0 -0
  66. data/test/form_test.rb +1 -0
  67. data/test/helper.rb +1 -0
  68. data/test/leak.rb +1 -0
  69. data/test/support_test.rb +4 -1
  70. data/test/testing.rb +1 -0
  71. data/test/validations_test.rb +176 -30
  72. metadata +120 -131
  73. data/b.rb +0 -38
  74. data/lib/dao/conducer/crud.rb +0 -70
  75. data/lib/dao/current.rb +0 -66
  76. data/lib/dao/image_cache.rb +0 -193
  77. data/lib/dao/rails/lib/generators/dao/templates/conducer_controller.rb +0 -79
  78. data/test/db.yml +0 -9
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Api
3
4
  # class methods
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Context
3
4
  Attrs = %w(
@@ -42,6 +43,7 @@ module Dao
42
43
  @result = Result.new
43
44
  @result.path = @path
44
45
  @result.route = @route
46
+ @result.status = @status
45
47
  @result.mode = @api.mode
46
48
  @result.params = @params
47
49
  @result.errors = @params.errors
data/lib/dao/api/dsl.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Api
3
4
  class DSL < BlankSlate
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Api
3
4
  Initializers = {} unless defined?(Initializers)
data/lib/dao/api/modes.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Api
3
4
  class << Api
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class Api
3
4
  class << Api
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
3
  class BlankSlate
3
4
  instance_methods.each{|m| undef_method(m) unless m.to_s =~ /(^__)|object_id/}
data/lib/dao/conducer.rb CHANGED
@@ -1,36 +1,37 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  module Dao
2
-
3
- class Conducer
4
3
  ##
5
- #
6
- include ActiveModel::Naming
7
- #include ActiveModel::Conversion
8
-
9
- #extend ActiveModel::Translation
10
- #include ActiveModel::AttributeMethods
11
- #include ActiveModel::Serialization
12
- #include ActiveModel::Dirty
13
- #include ActiveModel::MassAssignmentSecurity
14
- #include ActiveModel::Observing
15
- #include ActiveModel::Serializers::JSON
16
- #include ActiveModel::Serializers::Xml
17
-
18
- #include ActiveModel::Validations
19
-
20
- extend ActiveModel::Callbacks
21
-
22
- define_model_callbacks(:save, :create, :update, :destroy)
23
- define_model_callbacks(:reset, :initialize, :find, :touch)
24
- include ActiveModel::Validations::Callbacks
4
+ #
5
+ Dao.load('conducer/attributes.rb')
6
+ Dao.load('conducer/collection.rb')
7
+ Dao.load('conducer/active_model.rb')
8
+ Dao.load('conducer/controller_support.rb')
9
+ Dao.load('conducer/callback_support.rb')
10
+ Dao.load('conducer/view_support.rb')
11
+ Dao.load('conducer/nav_support.rb')
25
12
 
26
13
  ##
27
14
  #
15
+ class Conducer
16
+ ##
17
+ #
28
18
  include Dao::Validations
29
- include Dao::Current
30
19
 
31
- ## class_methods
32
- #
20
+ ## class_methods
21
+ #
33
22
  class << Conducer
23
+ def inherited(other)
24
+ super
25
+ ensure
26
+ other.build_collection_class!
27
+ subclasses.push(other)
28
+ subclasses.uniq!
29
+ end
30
+
31
+ def subclasses
32
+ defined?(@@subclasses) ? @@subclasses : (@@subclasses = [])
33
+ end
34
+
34
35
  def name(*args)
35
36
  return send('name=', args.first) unless args.empty?
36
37
  @name ||= super
@@ -40,43 +41,16 @@ module Dao
40
41
  @name = name.to_s
41
42
  end
42
43
 
43
- def model_name(*args)
44
- return send('model_name=', args.first) unless args.empty?
45
- @model_name ||= default_model_name
46
- end
47
-
48
- def model_name=(model_name)
49
- @model_name = model_name_for(model_name)
50
- end
51
-
52
- def model_name_for(model_name)
53
- ActiveModel::Name.new(Map[:name, model_name])
54
- end
55
-
56
- def default_model_name
57
- model_name_for(name.to_s.sub(/Conducer$/, ''))
58
- end
59
-
60
- def table_name
61
- @table_name ||= model_name.plural.to_s
62
- end
63
- alias_method('collection_name', 'table_name')
64
-
65
- def table_name=(table_name)
66
- @table_name = table_name.to_s
67
- end
68
- alias_method('collection_name=', 'table_name=')
69
-
70
44
  def controller
71
- defined?(@controller) ? @controller : Dao.current_controller
45
+ Dao.current_controller || Dao.mock_controller
72
46
  end
73
47
 
74
48
  def controller=(controller)
75
- @controller = controller
49
+ Dao.current_controller = controller
76
50
  end
77
51
 
78
- def mock_controller(*args, &block)
79
- Dao.mock_controller(*args, &block)
52
+ def current
53
+ @current ||= (defined?(::Current) ? ::Current : Map.new)
80
54
  end
81
55
 
82
56
  def raise!(*args, &block)
@@ -93,324 +67,382 @@ module Dao
93
67
  end
94
68
  end
95
69
 
96
- ## contructor
97
- #
98
- %w(
99
- name
100
- attributes
101
- errors
102
- form
103
- ).each{|a| fattr(a)}
104
-
105
- def self.new(*args, &block)
70
+ ## crud-y lifecycle ctors
71
+ #
72
+ def Conducer.for(action, *args, &block)
106
73
  allocate.tap do |conducer|
107
- conducer.running_callbacks(:reset, :initialize) do
108
- conducer.send(:reset, *args, &block)
109
- conducer.send(:initialize, *args, &block)
110
- end
74
+ action = Action.new(action, conducer)
75
+ Dao.call(conducer, :init, action, *args, &block)
76
+ Dao.call(conducer, :initialize, *args, &block)
111
77
  end
112
78
  end
113
79
 
114
- def running_callbacks(*args, &block)
115
- which = args.shift
116
- if args.empty?
117
- run_callbacks(which, &block)
118
- else
119
- run_callbacks(which){ running_callbacks(*args, &block) }
80
+ def Conducer.call(*args, &block)
81
+ self.for(*args, &block)
82
+ end
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)
88
+ end
89
+ __
90
+ end
91
+
92
+ ## ctor
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)
120
98
  end
121
99
  end
122
100
 
123
- def reset(*args, &block)
101
+ %w[
102
+ name
103
+ attributes
104
+ form
105
+ params
106
+ errors
107
+ status
108
+ models
109
+ model
110
+ conduces
111
+ ].each{|attr| fattr(attr)}
112
+
113
+ ## init runs *before* initialize - aka inside allocate
114
+ #
115
+ def init(*args, &block)
124
116
  controllers, args = args.partition{|arg| arg.is_a?(ActionController::Base)}
117
+ actions, args = args.partition{|arg| arg.is_a?(Action)}
118
+ models, args = args.partition{|arg| arg.respond_to?(:persisted?) }
125
119
  hashes, args = args.partition{|arg| arg.is_a?(Hash)}
126
120
 
127
- @name = self.class.model_name.singular
121
+ @name = self.class.model_name.singular.sub(/_+$/, '')
128
122
  @attributes = Attributes.for(self)
129
123
  @form = Form.for(self)
124
+ @params = Map.new
130
125
 
131
- validator.reset
126
+ @errors = validator.errors
127
+ @status = validator.status
132
128
 
133
129
  set_controller(controllers.shift || Dao.current_controller || Dao.mock_controller)
134
130
 
135
- hashes.each do |hash|
136
- hash.each do |key, val|
137
- @attributes.set(key_for(key) => val)
138
- end
139
- end
131
+ set_action(actions.shift) unless actions.empty?
140
132
 
141
- self
133
+ set_models(models)
134
+
135
+ set_mounts(self.class.mounted)
136
+
137
+ update_params(hashes)
138
+
139
+ @default_initialize = nil
142
140
  end
143
141
 
144
- def errors
145
- validator.errors
142
+ def set_models(*models)
143
+ @models =
144
+ models.flatten.compact
145
+
146
+ candidates =
147
+ @models.select{|model| model.class.model_name == self.class.model_name}
148
+
149
+ @model =
150
+ case candidates.size == 1
151
+ when 1
152
+ candidates.first
153
+ else
154
+ @models.first
155
+ end
156
+
157
+ @models.each do |model|
158
+ key = model_key_for(model)
159
+ ivar = "@#{ key }"
160
+ instance_variable_set(ivar, model) unless instance_variable_defined?(ivar)
161
+ end
146
162
  end
147
163
 
148
- def status
149
- validator.status
164
+ def update_params(*hashes)
165
+ hashes.flatten.compact.each{|hash| @params.apply(hash)}
150
166
  end
151
167
 
168
+ ## a sane initialize is provided for you. you are free to override it
169
+ # *** without *** calling super
170
+ #
152
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?
153
175
  end
154
176
 
155
- ## instance_methods
156
- #
157
- def inspect
158
- ::JSON.pretty_generate(@attributes, :max_nesting => 0)
177
+ def set_mounts(list)
178
+ list.each do |args, block|
179
+ mount(*args, &block)
180
+ end
159
181
  end
160
182
 
161
- def id
162
- @attributes[:id] || @attributes[:_id]
183
+ def model_key_for(model)
184
+ case model
185
+ when String
186
+ model
187
+ else
188
+ model.class.name
189
+ end.demodulize.underscore
163
190
  end
164
191
 
165
- def id=(id)
166
- @attributes[:id] = id
192
+ def initialize_for_action(*args, &block)
193
+ @action.call(:initialize, *args, &block)
167
194
  end
168
195
 
169
- def key_for(*keys)
170
- keys.flatten.map{|key| key =~ %r/^\d+$/ ? Integer(key) : key}
171
- #key = keys.flatten.join('.').strip
172
- #key.split(%r/\s*[,.]\s*/).map{|key| key =~ %r/^\d+$/ ? Integer(key) : key}
196
+ def conduces(*args)
197
+ if args.empty?
198
+ @model
199
+ else
200
+ @model = args.flatten.compact.first
201
+ @models.delete(@model)
202
+ @models.unshift(@model)
203
+ @model
204
+ end
173
205
  end
206
+ alias_method(:set_model, :conduces)
174
207
 
175
- def [](key)
176
- @attributes.get(key_for(key))
208
+ def conduces=(model)
209
+ conduces(model)
177
210
  end
178
211
 
179
- def []=(key, val)
180
- @attributes.set(key_for(key), val)
212
+ def conduces?(model)
213
+ conduces == model
181
214
  end
182
215
 
183
- %w( set get has? update ).each do |m|
184
- module_eval <<-__, __FILE__, __LINE__
185
- def #{ m }(*a, &b)
186
- @attributes.#{ m }(*a, &b)
216
+ def update_models(*models)
217
+ models.flatten.compact.each do |model|
218
+ if conduces?(model)
219
+ update_attributes(model.attributes)
220
+ else
221
+ update_attributes(model_key_for(model), model.attributes)
187
222
  end
188
- __
223
+ end
189
224
  end
190
225
 
191
- def method_missing(method, *args, &block)
192
- case method.to_s
193
- when /^(.*)[=]$/
194
- key = key_for($1)
195
- val = args.first
196
- @attributes.set(key => val)
197
-
198
- when /^(.*)[!]$/
199
- key = key_for($1)
200
- val = true
201
- @attributes.set(key => val)
226
+ def update_attributes(*args, &block)
227
+ attributes =
228
+ case
229
+ when args.size == 1 && args.first.is_a?(Hash)
230
+ args.first
231
+ else
232
+ if args.size >= 2
233
+ val = args.pop
234
+ key = args.flatten.compact
235
+ {key => val}
236
+ else
237
+ {}
238
+ end
239
+ end
202
240
 
203
- when /^(.*)[?]$/
204
- key = key_for($1)
205
- @attributes.has?(key)
241
+ @attributes.set(attributes)
206
242
 
207
- else
208
- key = key_for(method)
209
- return @attributes.get(key) if @attributes.has?(key)
210
- super
211
- end
212
- end
243
+ update_mounted_attributes!
213
244
 
214
- def inspect
215
- "#{ self.class.name }(#{ @attributes.inspect.chomp })"
245
+ @attributes
216
246
  end
217
247
 
218
- # active_model support
219
- #
220
-
248
+ def update_mounted_attributes!
249
+ deepest_mounts_first = mounted.sort_by{|mnt| mnt._key.size}.reverse
221
250
 
222
- ## include ActiveModel::Conversion
223
- #
224
- def to_model
225
- self
251
+ deepest_mounts_first.each do |mount|
252
+ value = @attributes.get(mount._key)
253
+ mount._set(value) if mount.respond_to?(:_set)
254
+ @attributes.set(mount._key => mount)
255
+ end
226
256
  end
227
257
 
228
- def to_key
229
- id ? [id] : nil
258
+ def update_attributes!(*args, &block)
259
+ update_attributes(*args, &block)
260
+ ensure
261
+ save!
230
262
  end
231
263
 
232
- def to_param
233
- persisted? ? to_key.join('-') : nil
264
+ def attributes=(attributes)
265
+ @attributes.clear
266
+ update_attributes(attributes)
234
267
  end
235
268
 
236
- def persisted
237
- !!(defined?(@persisted) ? @persisted : id)
238
- end
239
- def persisted?
240
- persisted
241
- end
242
- def persisted=(value)
243
- @persisted = !!value
244
- end
245
- def persisted!
246
- self.persisted = true
269
+ def set(*args, &block)
270
+ update_attributes(*args, &block)
247
271
  end
248
272
 
249
- def new_record
250
- !!(defined?(@new_record) ? @new_record : id.blank?)
251
- end
252
- def new_record?
253
- new_record
273
+ def has?(*key)
274
+ key = key_for(key)
275
+ @attributes.has?(key)
254
276
  end
255
- def new_record=(value)
256
- @new_record = !!value
277
+
278
+ def get(*key)
279
+ key = key_for(key)
280
+ @attributes.get(key)
257
281
  end
258
- def new_record!
259
- self.new_record = true
282
+
283
+ def [](key)
284
+ get(key)
260
285
  end
261
286
 
262
- def destroyed
263
- !!(defined?(@destroyed) ? @destroyed : id.blank?)
287
+ def []=(key, val)
288
+ set(key, val)
264
289
  end
265
- def destroyed?
266
- destroyed
290
+
291
+ def method_missing(method, *args, &block)
292
+ re = /^([^=!?]+)([=!?])?$/imox
293
+
294
+ matched, key, suffix = re.match(method.to_s).to_a
295
+
296
+ case suffix
297
+ when '='
298
+ set(key, args.first)
299
+ when '!'
300
+ set(key, args.size > 0 ? args.first : true)
301
+ when '?'
302
+ has?(key)
303
+ else
304
+ case key
305
+ when /^current_(.*)/
306
+ Current.send($1)
307
+ else
308
+ has?(key) ? get(key) : super
309
+ end
310
+ end
267
311
  end
268
- def destroyed=(value)
269
- @destroyed = !!value
312
+
313
+ ## id support
314
+ #
315
+ def id(*args)
316
+ if args.blank?
317
+ @attributes[:_id] || @attributes[:id]
318
+ else
319
+ id = args.flatten.compact.shift
320
+ key = [:_id, :id].detect{|k| @attributes.has_key?(k)} || :id
321
+ @attributes[key] = id_for(id)
322
+ end
270
323
  end
271
- def destroyed!
272
- self.destroyed = true
324
+
325
+ def id?
326
+ self.id
273
327
  end
274
328
 
329
+ def id=(id)
330
+ self.id(id)
331
+ end
275
332
 
276
- ## extend ActiveModel::Translation
277
- #
278
- def self.human_attribute_name(attribute, options = {})
279
- attribute
333
+ def id!(id)
334
+ self.id(id)
280
335
  end
281
336
 
282
- def self.lookup_ancestors
283
- [self]
337
+ def id_for(object)
338
+ model?(object) ? object.id : object
284
339
  end
285
340
 
286
- def read_attribute_for_validation(key)
287
- self[key]
341
+ def model?(object)
342
+ object.respond_to?(:persisted?)
288
343
  end
289
344
 
290
- ## view support
291
- #
292
- url_helpers = Rails.application.try(:routes).try(:url_helpers)
293
- include(url_helpers) if url_helpers
294
- include(ActionView::Helpers) if defined?(ActionView::Helpers)
345
+ ## mixin controller support
346
+ #
347
+ module_eval(&ControllerSupport)
295
348
 
296
- def controller
297
- @controller ||= (Dao.current_controller || Dao.mock_controller)
298
- @controller
299
- end
349
+ ## mixin callback support
350
+ #
351
+ module_eval(&CallbackSupport)
300
352
 
301
- def controller=(controller)
302
- @controller = controller
303
- ensure
304
- default_url_options[:protocol] = @controller.request.protocol
305
- default_url_options[:host] = @controller.request.host
306
- default_url_options[:port] = @controller.request.port
307
- end
353
+ ## mixin view support
354
+ #
355
+ module_eval(&ViewSupport)
308
356
 
309
- def set_controller(controller)
310
- self.controller = controller
357
+ ##
358
+ #
359
+ def save
360
+ default_save
311
361
  end
312
362
 
313
- controller_delegates = %w(
314
- render
315
- render_to_string
316
- )
363
+ def default_save
364
+ return false unless valid?
317
365
 
318
- controller_delegates.each do |method|
319
- module_eval <<-__, __FILE__, __LINE__
320
- def #{ method }(*args, &block)
321
- controller.#{ method }(*args, &block)
366
+ if @model
367
+ attributes = self.attributes.dup
368
+
369
+ @models.each do |model|
370
+ next if model == @model
371
+ key = model_key_for(model)
372
+ attributes.delete(key)
322
373
  end
323
- __
324
- end
325
374
 
326
- ## generic crud support assuming valid .all, .find, #save and #destroy
327
- #
328
- =begin
329
- def self.create(*args, &block)
330
- allocate.tap do |conducer|
331
- conducer.running_callbacks :reset, :initialize, :create do
332
- conducer.send(:reset, *args, &block)
333
- conducer.send(:initialize, *args, &block)
334
- return false unless conducer.save
375
+ mounted.each do |mnt|
376
+ attributes.set(mnt._key, mnt._value)
335
377
  end
336
- end
337
- end
338
378
 
339
- def self.create!(*args, &block)
340
- allocate.tap do |conducer|
341
- conducer.running_callbacks :reset, :initialize, :create do
342
- conducer.send(:reset, *args, &block)
343
- conducer.send(:initialize, *args, &block)
344
- raise!(:validation_error) unless conducer.save
379
+ @model.update_attributes(attributes)
380
+
381
+ if @model.save
382
+ mounted.each{|mnt| mnt._clear}
383
+ return true
384
+ else
385
+ errors.relay(@model.errors)
386
+ return false
345
387
  end
388
+ else
389
+ raise NotImplementedError
346
390
  end
347
391
  end
348
-
349
- def self.blank(params = {})
350
- new
392
+
393
+ def save!
394
+ raise!(:validation_error, errors) unless !!save
395
+ true
351
396
  end
352
397
 
353
- def self.build(params = {})
354
- new
398
+ def destroy
399
+ if @model and @model.destroy
400
+ return true
401
+ else
402
+ raise NotImplementedError
403
+ end
355
404
  end
356
405
 
357
- def self.show(id)
358
- find(id)
406
+ def destroy!
407
+ raise!(:deletion_error) unless !!destroy
408
+ true
359
409
  end
360
410
 
361
- def self.index(params = {})
362
- all(params)
411
+ ## misc
412
+ #
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
363
420
  end
364
421
 
365
- def self.edit(id)
366
- find(id)
422
+ def mounted
423
+ @mounted ||= []
367
424
  end
368
425
 
369
- def self.update(id)
370
- find(id)
426
+ def self.mount(*args, &block)
427
+ mounted.push([args, block])
371
428
  end
372
429
 
373
- def self.destroy(id)
374
- find(id)
430
+ def self.mounted
431
+ @mounted ||= []
375
432
  end
376
- =end
377
433
 
378
- ##
379
- #
380
-
381
- ##
382
- #
383
- def reload
384
- attributes =
385
- if id
386
- conducer = self.class.find(id)
387
- conducer ? conducer.attributes : {}
388
- else
389
- {}
390
- end
391
- reset(attributes)
392
- self
434
+ def key_for(key)
435
+ Dao.key_for(key)
393
436
  end
394
437
 
395
- def save!
396
- saved = !!save
397
- raise!(:validation_error) unless saved
398
- true
399
- end
400
-
401
- def update_attributes(attributes = {})
402
- @attributes.set(attributes)
403
- @attributes
438
+ def errors
439
+ validator.errors
404
440
  end
405
441
 
406
- def update_attributes!(*args, &block)
407
- update_attributes(*args, &block)
408
- ensure
409
- save!
442
+ def status
443
+ validator.status
410
444
  end
411
445
 
412
- ## misc
413
- #
414
446
  def model_name
415
447
  self.class.model_name
416
448
  end
@@ -419,19 +451,28 @@ module Dao
419
451
  @form
420
452
  end
421
453
 
454
+ def helper
455
+ @helper ||= ::Helper.new
456
+ end
457
+
422
458
  def raise!(*args, &block)
423
459
  self.class.raise!(*args, &block)
424
460
  end
425
461
 
426
- def as_json
462
+ def as_json(*args, &block)
427
463
  @attributes
428
464
  end
429
465
 
430
466
  def conducer
431
467
  self
432
468
  end
433
- end
434
469
 
435
- Dao.load('conducer/attributes.rb')
436
- Dao.load('conducer/crud.rb')
470
+ def inspect
471
+ "#{ self.class.name }(#{ @attributes.inspect.chomp })"
472
+ end
473
+
474
+ def to_s
475
+ inspect
476
+ end
477
+ end
437
478
  end