dao 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +96 -17
- data/Rakefile +92 -43
- data/dao.gemspec +12 -8
- data/lib/dao.rb +33 -20
- data/lib/dao/active_record.rb +51 -43
- data/lib/dao/api.rb +1 -1
- data/lib/dao/api/context.rb +6 -6
- data/lib/dao/api/dsl.rb +2 -2
- data/lib/dao/api/interfaces.rb +232 -0
- data/lib/dao/api/modes.rb +9 -6
- data/lib/dao/data.rb +7 -0
- data/lib/dao/errors.rb +27 -30
- data/lib/dao/form.rb +52 -28
- data/lib/dao/instance_exec.rb +37 -0
- data/lib/dao/interface.rb +16 -0
- data/lib/dao/params.rb +48 -24
- data/lib/dao/path.rb +1 -1
- data/lib/dao/rails.rb +5 -2
- data/lib/dao/rails/app/api.rb +1 -1
- data/lib/dao/rails/lib/generators/dao/dao_generator.rb +12 -0
- data/lib/dao/rails/lib/generators/dao/templates/api.rb +7 -1
- data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +25 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.css +27 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.js +149 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +10 -0
- data/lib/dao/result.rb +53 -14
- data/lib/dao/status.rb +162 -1
- data/lib/dao/stdext.rb +6 -0
- data/lib/dao/support.rb +10 -2
- data/lib/dao/validations.rb +338 -14
- data/sample/rails_app/pubic/javascripts/dao.js +148 -0
- data/test/dao_test.rb +18 -19
- metadata +29 -18
- data/TODO +0 -37
- data/db/dao.yml +0 -8
data/README
CHANGED
@@ -2,29 +2,109 @@ NAME
|
|
2
2
|
dao
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
|
-
a library for structuring rails applications using the 'data
|
5
|
+
a sa-weet-ass library for structuring rails applications using the 'data
|
6
|
+
access object' design pattern.
|
6
7
|
|
7
8
|
DESCRITPION
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
applications that are written on dao look like this in ruby
|
10
|
+
|
11
|
+
result = api.call('/posts/new', params)
|
12
|
+
|
13
|
+
and like this in javascript
|
14
|
+
|
15
|
+
result = api.call('/posts/new', params)
|
16
|
+
|
17
|
+
in command-line applications they look like this
|
18
|
+
|
19
|
+
result = api.call('/posts/new', params)
|
20
|
+
|
21
|
+
and in tests this syntax is used
|
22
|
+
|
23
|
+
result = api.call('/posts/new', params)
|
24
|
+
|
25
|
+
when a developer wants to understand the interface of a dao application she
|
26
|
+
does this
|
27
|
+
|
28
|
+
vi app/api.rb
|
29
|
+
|
30
|
+
when a developer of a dao application wants to play with a dao application
|
31
|
+
interactively she does
|
32
|
+
|
33
|
+
(rails console)
|
34
|
+
|
35
|
+
> api = Api.new
|
36
|
+
> result = api.call('/posts/new', params)
|
37
|
+
|
38
|
+
when a remote client wants to understand the api of a dao application she
|
39
|
+
does
|
40
|
+
|
41
|
+
curl --silent http://dao.app.com/api | less
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
this kind of brutally consistent interface is made possible by structuring
|
46
|
+
access to data around the finest data structure of all time - the hash. in
|
47
|
+
the case of dao the hash is a well structured and slightly clever hash, but
|
48
|
+
a simple hash interface is the basis of every bit of goodness dao has to
|
49
|
+
offer.
|
50
|
+
|
51
|
+
in dao, application developers do not bring models into controllers and,
|
52
|
+
especially not into views. instead, a unified interface to application
|
53
|
+
logic and data is used everywhere: in tests, in controllers, from the
|
54
|
+
command-line, and also from javascript.
|
55
|
+
|
56
|
+
this speration of concerns brings with it many, many desirable qualities:
|
57
|
+
|
58
|
+
- total seperation of concerns between the front and back end of a web
|
59
|
+
application. when developers are using dao changes to the data model
|
60
|
+
have zero effect on controllers and views.
|
61
|
+
|
62
|
+
- issues related to having models in controllers and views such as
|
63
|
+
difficulty reasoning about caching and n+1 queries in views killing the
|
64
|
+
db simply disappear.
|
65
|
+
|
66
|
+
- bad programming practices like using quasi-global variables
|
67
|
+
(current_user) or decorating models with view specific attributes
|
68
|
+
(password_verification) are no longer needed.
|
69
|
+
|
70
|
+
- developers are able to reason over the abilities of an application by
|
71
|
+
reading only a few source files.
|
72
|
+
|
73
|
+
- databases can be swapped, mixed, or alternate storage/caching mechanisms
|
74
|
+
added at any time without affecting the application's controllers or
|
75
|
+
views.
|
76
|
+
|
77
|
+
- transition from form based views to semi-ajax ones to fully-ajax ones is
|
78
|
+
direct.
|
79
|
+
|
80
|
+
- forms and interfaces that involve dozens of models are as easy to deal
|
81
|
+
with as simple ones.
|
82
|
+
|
83
|
+
- code can be optimized at the interface
|
84
|
+
|
85
|
+
|
86
|
+
wikipedia has this to say about dao in general
|
87
|
+
|
88
|
+
"
|
89
|
+
|
90
|
+
In computer software, a data access object (DAO) is an object that
|
91
|
+
provides an abstract interface to some type of database or persistence
|
92
|
+
mechanism, providing some specific operations without exposing details
|
93
|
+
of the database. It provides a mapping from application calls to the
|
94
|
+
persistence layer. This isolation separates the concerns of what data
|
95
|
+
accesses the application needs, in terms of domain-specific objects and
|
96
|
+
data types (the public interface of the DAO), and how these needs can be
|
97
|
+
satisfied with a specific DBMS, database schema, etc. (the
|
98
|
+
implementation of the DAO).
|
99
|
+
|
100
|
+
"
|
101
|
+
- http://en.wikipedia.org/wiki/Data_access_object
|
22
102
|
|
23
103
|
READING
|
24
|
-
http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
|
25
104
|
http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/dao.html
|
26
105
|
http://www.codefutures.com/data-access-object/
|
27
106
|
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
|
107
|
+
http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
|
28
108
|
|
29
109
|
INSTALL
|
30
110
|
gem 'dao', :path => File.expand_path('..') ### Gemfile
|
@@ -32,4 +112,3 @@ INSTALL
|
|
32
112
|
vim -o app/api.rb app/controllers/api_controller.rb
|
33
113
|
curl --silent http://0.0.0.0:3000/api
|
34
114
|
curl --silent http://0.0.0.0:3000/api/ping
|
35
|
-
|
data/Rakefile
CHANGED
@@ -83,14 +83,16 @@ task :gemspec do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
lib = This.lib
|
86
|
-
|
86
|
+
namespace = This.namespace
|
87
87
|
version = This.version
|
88
88
|
files = shiteless[Dir::glob("**/**")]
|
89
89
|
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
90
90
|
has_rdoc = true #File.exist?('doc')
|
91
91
|
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
92
|
-
|
93
|
-
|
92
|
+
|
93
|
+
summary = namespace.respond_to?(:summary) ? namespace.summary : "summary: #{ lib } kicks the ass"
|
94
|
+
description = namespace.respond_to?(:description) ? namespace.description : "description: #{ lib } kicks the ass"
|
95
|
+
dependencies = namespace.respond_to?(:dependencies) ? namespace.dependencies : []
|
94
96
|
|
95
97
|
if This.extensions.nil?
|
96
98
|
This.extensions = []
|
@@ -103,44 +105,48 @@ task :gemspec do
|
|
103
105
|
|
104
106
|
template =
|
105
107
|
if test(?e, 'gemspec.erb')
|
106
|
-
|
108
|
+
IO.read('gemspec.erb')
|
107
109
|
else
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
spec.
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
110
|
+
<<-__
|
111
|
+
## <%= lib %>.gemspec
|
112
|
+
#
|
113
|
+
|
114
|
+
Gem::Specification::new do |spec|
|
115
|
+
spec.name = <%= lib.inspect %>
|
116
|
+
spec.version = <%= version.inspect %>
|
117
|
+
spec.platform = Gem::Platform::RUBY
|
118
|
+
spec.summary = <%= lib.inspect %>
|
119
|
+
spec.description = <%= description.inspect %>
|
120
|
+
|
121
|
+
spec.files = <%= files.inspect %>
|
122
|
+
spec.executables = <%= executables.inspect %>
|
123
|
+
|
124
|
+
spec.require_path = "lib"
|
125
|
+
|
126
|
+
spec.has_rdoc = <%= has_rdoc.inspect %>
|
127
|
+
|
128
|
+
<% if defined?(test_files) %>
|
129
|
+
spec.test_files = <%= test_files.inspect %>
|
130
|
+
<% end %>
|
131
|
+
|
132
|
+
<% dependencies.each do |dependency|
|
133
|
+
lib, spec = dependency
|
134
|
+
%>
|
135
|
+
spec.add_dependency(*<%= spec.inspect %>)
|
136
|
+
<% end %>
|
137
|
+
|
138
|
+
spec.extensions.push(*<%= extensions.inspect %>)
|
139
|
+
|
140
|
+
spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
|
141
|
+
spec.author = <%= This.author.inspect %>
|
142
|
+
spec.email = <%= This.email.inspect %>
|
143
|
+
spec.homepage = <%= This.homepage.inspect %>
|
144
|
+
end
|
145
|
+
__
|
142
146
|
end
|
143
147
|
|
148
|
+
template = Template{ template }
|
149
|
+
|
144
150
|
Fu.mkdir_p(This.pkgdir)
|
145
151
|
This.gemspec = File.join(This.dir, "#{ This.lib }.gemspec") #File.join(This.pkgdir, "gemspec.rb")
|
146
152
|
open("#{ This.gemspec }", "w"){|fd| fd.puts(template)}
|
@@ -231,6 +237,7 @@ BEGIN {
|
|
231
237
|
require 'erb'
|
232
238
|
require 'fileutils'
|
233
239
|
require 'rbconfig'
|
240
|
+
require 'yaml'
|
234
241
|
|
235
242
|
# fu shortcut
|
236
243
|
#
|
@@ -244,28 +251,70 @@ BEGIN {
|
|
244
251
|
This.dir = File.dirname(This.file)
|
245
252
|
This.pkgdir = File.join(This.dir, 'pkg')
|
246
253
|
|
254
|
+
# use pkg.yml iff present
|
255
|
+
#
|
256
|
+
pkg_config_yml = File.join(This.dir, 'pkg/config.yml')
|
257
|
+
if test(?e, pkg_config_yml)
|
258
|
+
pkg_config = YAML::load(ERB.new(IO.read(pkg_config_yml)).result)
|
259
|
+
|
260
|
+
if pkg_config.is_a?(Hash)
|
261
|
+
ENV['LIB'] ||= pkg_config['lib']
|
262
|
+
ENV['AUTOREQUIRE'] ||= pkg_config['autorequire']
|
263
|
+
ENV['VERSION'] ||= pkg_config['version']
|
264
|
+
ENV['NAME'] ||= pkg_config['name']
|
265
|
+
ENV['NAMESPACE'] ||= pkg_config['namespace']
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
247
269
|
# grok lib
|
248
270
|
#
|
249
271
|
lib = ENV['LIB']
|
250
272
|
unless lib
|
251
|
-
lib = File.basename(
|
273
|
+
lib = File.basename(This.dir).sub(/[-].*$/, '')
|
252
274
|
end
|
253
275
|
This.lib = lib
|
254
276
|
|
277
|
+
# grok autorequire
|
278
|
+
#
|
279
|
+
autorequire = ENV['AUTOREQUIRE']
|
280
|
+
unless autorequire
|
281
|
+
autorequire = File.join(This.dir, 'lib', This.lib)
|
282
|
+
end
|
283
|
+
This.autorequire = autorequire
|
284
|
+
|
285
|
+
# load the package
|
286
|
+
#
|
287
|
+
require This.autorequire
|
288
|
+
|
289
|
+
# grok name
|
290
|
+
#
|
291
|
+
name = ENV['NAME']
|
292
|
+
unless name
|
293
|
+
name = This.lib.capitalize
|
294
|
+
end
|
295
|
+
This.name = name
|
296
|
+
|
297
|
+
# grok namespace
|
298
|
+
#
|
299
|
+
namespace = ENV['NAMESPACE']
|
300
|
+
unless namespace
|
301
|
+
namespace = This.name
|
302
|
+
end
|
303
|
+
This.namespace = eval(namespace)
|
304
|
+
|
255
305
|
# grok version
|
256
306
|
#
|
257
307
|
version = ENV['VERSION']
|
258
308
|
unless version
|
259
|
-
|
260
|
-
This.name = lib.capitalize
|
261
|
-
This.object = eval(This.name)
|
262
|
-
version = This.object.send(:version)
|
309
|
+
version = This.namespace.send(:version)
|
263
310
|
end
|
264
311
|
This.version = version
|
265
312
|
|
266
313
|
# we need to know the name of the lib an it's version
|
267
314
|
#
|
268
315
|
abort('no lib') unless This.lib
|
316
|
+
abort('no name') unless This.name
|
317
|
+
abort('no namespace') unless This.namespace
|
269
318
|
abort('no version') unless This.version
|
270
319
|
|
271
320
|
# discover full path to this ruby executable
|
data/dao.gemspec
CHANGED
@@ -2,24 +2,28 @@
|
|
2
2
|
#
|
3
3
|
|
4
4
|
Gem::Specification::new do |spec|
|
5
|
-
spec.name = "dao"
|
6
|
-
spec.version = "2.
|
5
|
+
spec.name = "dao"
|
6
|
+
spec.version = "2.1.0"
|
7
7
|
spec.platform = Gem::Platform::RUBY
|
8
8
|
spec.summary = "dao"
|
9
9
|
spec.description = "description: dao kicks the ass"
|
10
10
|
|
11
|
-
spec.files = ["dao.gemspec", "
|
11
|
+
spec.files = ["dao.gemspec", "lib", "lib/dao", "lib/dao/active_record.rb", "lib/dao/api", "lib/dao/api/context.rb", "lib/dao/api/dsl.rb", "lib/dao/api/endpoints.rb", "lib/dao/api/initializers.rb", "lib/dao/api/interfaces.rb", "lib/dao/api/modes.rb", "lib/dao/api.rb", "lib/dao/blankslate.rb", "lib/dao/data.rb", "lib/dao/db.rb", "lib/dao/endpoint.rb", "lib/dao/engine.rb", "lib/dao/errors.rb", "lib/dao/exceptions.rb", "lib/dao/form.rb", "lib/dao/instance_exec.rb", "lib/dao/interface.rb", "lib/dao/mode.rb", "lib/dao/mongo_mapper.rb", "lib/dao/params.rb", "lib/dao/path.rb", "lib/dao/rails", "lib/dao/rails/app", "lib/dao/rails/app/api.rb", "lib/dao/rails/app/controllers", "lib/dao/rails/app/controllers/api_controller.rb", "lib/dao/rails/engine", "lib/dao/rails/lib", "lib/dao/rails/lib/generators", "lib/dao/rails/lib/generators/dao", "lib/dao/rails/lib/generators/dao/api_generator.rb", "lib/dao/rails/lib/generators/dao/dao_generator.rb", "lib/dao/rails/lib/generators/dao/templates", "lib/dao/rails/lib/generators/dao/templates/api.rb", "lib/dao/rails/lib/generators/dao/templates/api_controller.rb", "lib/dao/rails/lib/generators/dao/templates/dao.css", "lib/dao/rails/lib/generators/dao/templates/dao.js", "lib/dao/rails/lib/generators/dao/templates/dao_helper.rb", "lib/dao/rails/lib/generators/dao/USAGE", "lib/dao/rails.rb", "lib/dao/result.rb", "lib/dao/slug.rb", "lib/dao/status.rb", "lib/dao/stdext.rb", "lib/dao/support.rb", "lib/dao/validations.rb", "lib/dao.rb", "Rakefile", "README", "sample", "sample/rails_app", "sample/rails_app/app", "sample/rails_app/app/api.rb", "sample/rails_app/app/controllers", "sample/rails_app/app/controllers/api_controller.rb", "sample/rails_app/app/controllers/application_controller.rb", "sample/rails_app/app/helpers", "sample/rails_app/app/helpers/application_helper.rb", "sample/rails_app/app/mailers", "sample/rails_app/app/models", "sample/rails_app/app/views", "sample/rails_app/app/views/layouts", "sample/rails_app/app/views/layouts/application.html.erb", "sample/rails_app/config", "sample/rails_app/config/application.rb", "sample/rails_app/config/boot.rb", "sample/rails_app/config/database.yml", "sample/rails_app/config/environment.rb", "sample/rails_app/config/environments", "sample/rails_app/config/environments/development.rb", "sample/rails_app/config/environments/production.rb", "sample/rails_app/config/environments/test.rb", "sample/rails_app/config/initializers", "sample/rails_app/config/initializers/backtrace_silencers.rb", "sample/rails_app/config/initializers/inflections.rb", "sample/rails_app/config/initializers/mime_types.rb", "sample/rails_app/config/initializers/secret_token.rb", "sample/rails_app/config/initializers/session_store.rb", "sample/rails_app/config/locales", "sample/rails_app/config/locales/en.yml", "sample/rails_app/config/routes.rb", "sample/rails_app/config.ru", "sample/rails_app/db", "sample/rails_app/db/development.sqlite3", "sample/rails_app/db/seeds.rb", "sample/rails_app/doc", "sample/rails_app/doc/README_FOR_APP", "sample/rails_app/Gemfile", "sample/rails_app/Gemfile.lock", "sample/rails_app/lib", "sample/rails_app/lib/tasks", "sample/rails_app/log", "sample/rails_app/log/development.log", "sample/rails_app/log/production.log", "sample/rails_app/log/server.log", "sample/rails_app/log/test.log", "sample/rails_app/pubic", "sample/rails_app/pubic/javascripts", "sample/rails_app/pubic/javascripts/dao.js", "sample/rails_app/public", "sample/rails_app/public/404.html", "sample/rails_app/public/422.html", "sample/rails_app/public/500.html", "sample/rails_app/public/favicon.ico", "sample/rails_app/public/images", "sample/rails_app/public/images/rails.png", "sample/rails_app/public/index.html", "sample/rails_app/public/javascripts", "sample/rails_app/public/javascripts/application.js", "sample/rails_app/public/javascripts/controls.js", "sample/rails_app/public/javascripts/dragdrop.js", "sample/rails_app/public/javascripts/effects.js", "sample/rails_app/public/javascripts/prototype.js", "sample/rails_app/public/javascripts/rails.js", "sample/rails_app/public/robots.txt", "sample/rails_app/public/stylesheets", "sample/rails_app/Rakefile", "sample/rails_app/README", "sample/rails_app/script", "sample/rails_app/script/rails", "sample/rails_app/test", "sample/rails_app/test/fixtures", "sample/rails_app/test/functional", "sample/rails_app/test/integration", "sample/rails_app/test/performance", "sample/rails_app/test/performance/browsing_test.rb", "sample/rails_app/test/test_helper.rb", "sample/rails_app/test/unit", "sample/rails_app/tmp/cache", "sample/rails_app/tmp/pids", "sample/rails_app/tmp/sessions", "sample/rails_app/tmp/sockets", "sample/rails_app/vendor", "sample/rails_app/vendor/plugins", "test", "test/dao_test.rb", "test/helper.rb", "test/testing.rb", "test/units"]
|
12
12
|
spec.executables = []
|
13
13
|
|
14
14
|
spec.require_path = "lib"
|
15
15
|
|
16
16
|
spec.has_rdoc = true
|
17
|
-
spec.test_files = nil
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
spec.add_dependency(*["tagz", "~> 8.2.0"])
|
22
|
+
|
23
|
+
spec.add_dependency(*["map", "~> 2.6.1"])
|
24
|
+
|
25
|
+
spec.add_dependency(*["yajl-ruby", "~> 0.7.9"])
|
26
|
+
|
23
27
|
|
24
28
|
spec.extensions.push(*[])
|
25
29
|
|
data/lib/dao.rb
CHANGED
@@ -6,33 +6,23 @@
|
|
6
6
|
#require 'yaml'
|
7
7
|
#require 'yaml/store'
|
8
8
|
|
9
|
-
# gems
|
10
|
-
#
|
11
|
-
begin
|
12
|
-
require 'rubygems'
|
13
|
-
rescue LoadError
|
14
|
-
nil
|
15
|
-
end
|
16
|
-
|
17
|
-
if defined?(gem)
|
18
|
-
gem('map', '~> 2.2.2')
|
19
|
-
gem('tagz', '~> 8.0')
|
20
|
-
gem('yajl-ruby', '~> 0.7.9')
|
21
|
-
end
|
22
|
-
|
23
|
-
require 'map'
|
24
|
-
require 'tagz'
|
25
|
-
require 'yajl'
|
26
|
-
|
27
9
|
# dao libs
|
28
10
|
#
|
29
11
|
module Dao
|
30
|
-
Version = '2.
|
12
|
+
Version = '2.1.0' unless defined?(Version)
|
31
13
|
|
32
14
|
def version
|
33
15
|
Dao::Version
|
34
16
|
end
|
35
17
|
|
18
|
+
def dependencies
|
19
|
+
{
|
20
|
+
'map' => ['map', '~> 2.6.1'],
|
21
|
+
'tagz' => ['tagz', '~> 8.2.0'],
|
22
|
+
'yajl' => ['yajl-ruby', '~> 0.7.9']
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
36
26
|
def libdir(*args, &block)
|
37
27
|
@libdir ||= File.expand_path(__FILE__).sub(/\.rb$/,'')
|
38
28
|
args.empty? ? @libdir : File.join(@libdir, *args)
|
@@ -55,8 +45,24 @@
|
|
55
45
|
extend(Dao)
|
56
46
|
end
|
57
47
|
|
48
|
+
# gems
|
49
|
+
#
|
50
|
+
begin
|
51
|
+
require 'rubygems'
|
52
|
+
rescue LoadError
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
if defined?(gem)
|
57
|
+
Dao.dependencies.each do |lib, dependency|
|
58
|
+
gem(*dependency)
|
59
|
+
require(lib)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
58
63
|
Dao.load %w[
|
59
64
|
blankslate.rb
|
65
|
+
instance_exec.rb
|
60
66
|
exceptions.rb
|
61
67
|
support.rb
|
62
68
|
slug.rb
|
@@ -72,7 +78,7 @@
|
|
72
78
|
|
73
79
|
mode.rb
|
74
80
|
path.rb
|
75
|
-
|
81
|
+
interface.rb
|
76
82
|
api.rb
|
77
83
|
|
78
84
|
|
@@ -86,3 +92,10 @@
|
|
86
92
|
unless defined?(D)
|
87
93
|
D = Dao
|
88
94
|
end
|
95
|
+
|
96
|
+
if defined?(Rails.env)
|
97
|
+
unless Rails.env.production?
|
98
|
+
unloadable(Dao)
|
99
|
+
unloadable(D)
|
100
|
+
end
|
101
|
+
end
|
data/lib/dao/active_record.rb
CHANGED
@@ -8,68 +8,76 @@ end
|
|
8
8
|
if defined?(ActiveRecord)
|
9
9
|
|
10
10
|
module ActiveRecord
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
class Base
|
12
|
+
def Base.to_dao(*args)
|
13
|
+
if args.first.is_a?(Base)
|
14
|
+
record_to_dao(record = args.shift, *args)
|
15
|
+
else
|
15
16
|
@to_dao ||= (
|
16
|
-
column_names
|
17
|
-
)
|
18
|
-
|
19
|
-
unless args.empty?
|
20
|
-
@to_dao.clear
|
21
|
-
args.flatten.compact.each do |arg|
|
22
|
-
@to_dao.push(arg.to_s)
|
23
|
-
end
|
24
|
-
@to_dao.uniq!
|
25
|
-
@to_dao.map!{|name| name.to_s}
|
26
|
-
end
|
27
|
-
|
17
|
+
names = column_names ### + reflect_on_all_associations.map(&:name)
|
18
|
+
)
|
19
|
+
@to_dao = Array(args) unless args.empty?
|
28
20
|
@to_dao
|
29
21
|
end
|
22
|
+
end
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
24
|
+
def Base.to_dao=(*args)
|
25
|
+
to_dao(*args)
|
34
26
|
end
|
35
27
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
def Base.record_to_dao(record, *args)
|
29
|
+
model = record.class
|
30
|
+
map = Dao.map
|
31
|
+
map[:model] = model.name.underscore
|
32
|
+
map[:id] = record.id
|
40
33
|
|
41
|
-
|
34
|
+
list = args.empty? ? model.to_dao : args
|
42
35
|
|
43
|
-
|
44
|
-
|
36
|
+
list.each do |attr|
|
37
|
+
if attr.is_a?(Array)
|
38
|
+
related, *argv = attr
|
39
|
+
value = record.send(related).to_dao(*argv)
|
40
|
+
map[related] = value
|
41
|
+
next
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
if attr.is_a?(Hash)
|
45
|
+
attr.each do |related, argv|
|
46
|
+
value = record.send(related).to_dao(*argv)
|
47
|
+
map[related] = value
|
49
48
|
end
|
49
|
+
next
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
hash[attr] = value.map{|val| val.respond_to?(:to_dao) ? val.to_dao : val}
|
53
|
-
next
|
54
|
-
end
|
52
|
+
value = record.send(attr)
|
55
53
|
|
56
|
-
|
54
|
+
if value.respond_to?(:to_dao)
|
55
|
+
map[attr] = value.to_dao
|
56
|
+
next
|
57
57
|
end
|
58
58
|
|
59
|
-
if
|
60
|
-
|
59
|
+
if value.is_a?(Array)
|
60
|
+
map[attr] = value.map{|val| val.respond_to?(:to_dao) ? val.to_dao : val}
|
61
|
+
next
|
61
62
|
end
|
62
63
|
|
63
|
-
|
64
|
+
map[attr] = value
|
65
|
+
end
|
66
|
+
|
67
|
+
if map.has_key?(:_id) and not map.has_key?(:id)
|
68
|
+
map[:id] = map[:_id]
|
64
69
|
end
|
65
|
-
|
66
|
-
|
70
|
+
|
71
|
+
map
|
67
72
|
end
|
68
|
-
end
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
|
74
|
+
def to_dao(*args)
|
75
|
+
record = self
|
76
|
+
model = record.class
|
77
|
+
model.record_to_dao(record, *args)
|
78
|
+
end
|
79
|
+
alias_method('to_h', 'to_dao')
|
80
|
+
alias_method('to_map', 'to_dao') ### HACK
|
73
81
|
end
|
74
82
|
end
|
75
83
|
|