dao 4.2.1 → 4.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class DaoGenerator < Rails::Generators::NamedBase
|
2
3
|
source_root(File.expand_path('../templates', __FILE__))
|
3
4
|
|
@@ -5,9 +6,6 @@ class DaoGenerator < Rails::Generators::NamedBase
|
|
5
6
|
ARGV.shift if ARGV.first == name
|
6
7
|
|
7
8
|
case name
|
8
|
-
when /conducer_controller/
|
9
|
-
generate_conducer_controller!
|
10
|
-
|
11
9
|
when /conducer/
|
12
10
|
generate_conducer!
|
13
11
|
|
@@ -17,9 +15,6 @@ class DaoGenerator < Rails::Generators::NamedBase
|
|
17
15
|
when /api/
|
18
16
|
generate_system!
|
19
17
|
|
20
|
-
when /conducers/
|
21
|
-
generate_system!
|
22
|
-
|
23
18
|
when /assets/
|
24
19
|
generate_system!
|
25
20
|
|
@@ -29,13 +24,6 @@ class DaoGenerator < Rails::Generators::NamedBase
|
|
29
24
|
end
|
30
25
|
|
31
26
|
protected
|
32
|
-
def generate_conducer_controller!
|
33
|
-
@conducer_name = ARGV.shift.sub(/_?conducer$/i, '') + '_conducer'
|
34
|
-
@controller_name = @conducer_name.sub(/_conducer/, '_controller')
|
35
|
-
|
36
|
-
template "conducer_controller.rb", "app/controllers/#{ @conducer_name.underscore }.rb"
|
37
|
-
#template "conducer.rb", "app/conducers/#{ @conducer_name.underscore }.rb"
|
38
|
-
end
|
39
27
|
|
40
28
|
def generate_conducer!
|
41
29
|
@conducer_name = ARGV.shift.sub(/_?conducer$/i, '') + '_conducer'
|
@@ -43,34 +31,27 @@ protected
|
|
43
31
|
end
|
44
32
|
|
45
33
|
def generate_system!
|
46
|
-
|
34
|
+
FileUtils.mkdir_p(File.join(Rails.root, 'app/conducers'))
|
47
35
|
|
48
|
-
|
49
|
-
FileUtils.mkdir_p(File.join(dao_dir, 'apis'))
|
50
|
-
FileUtils.mkdir_p(File.join(dao_dir, 'conducers'))
|
51
|
-
|
52
|
-
copy_file("api.rb", "app/dao/api.rb")
|
36
|
+
copy_file("api.rb", "lib/api.rb")
|
53
37
|
|
54
38
|
copy_file("api_controller.rb", "app/controllers/api_controller.rb")
|
39
|
+
|
55
40
|
copy_file("dao_helper.rb", "app/helpers/dao_helper.rb")
|
56
41
|
|
57
|
-
copy_file("dao.js", "
|
58
|
-
copy_file("dao.css", "public/stylesheets/dao.css")
|
42
|
+
copy_file("dao.js", "app/assets/javascripts/dao.js")
|
59
43
|
|
60
|
-
|
44
|
+
copy_file("dao.css", "app/assets/stylesheets/dao.css")
|
61
45
|
|
62
|
-
|
46
|
+
route("match 'api(/*path)' => 'api#index', :as => 'api'")
|
63
47
|
|
64
48
|
application(
|
65
49
|
<<-__
|
66
50
|
|
67
51
|
config.after_initialize do
|
68
|
-
require '
|
69
|
-
require 'yajl/json_gem'
|
52
|
+
require File.join(Rails.root, 'lib/api.rb')
|
70
53
|
end
|
71
54
|
|
72
|
-
config.autoload_paths += %w( app/models app/dao app/dao/apis app/dao/conducers )
|
73
|
-
|
74
55
|
### config.action_view.javascript_expansions[:defaults] ||= []
|
75
56
|
### config.action_view.javascript_expansions[:defaults] += %( dao )
|
76
57
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
Api =
|
2
3
|
Dao.api do
|
3
4
|
##
|
@@ -21,7 +22,7 @@ Api =
|
|
21
22
|
call('/pong'){
|
22
23
|
require_current_user!
|
23
24
|
data.update :time => Time.now
|
24
|
-
data.update :current_user => current_user
|
25
|
+
data.update :current_user => current_user
|
25
26
|
}
|
26
27
|
|
27
28
|
## this is simply a suggested way to model your api. it is not required.
|
@@ -1,4 +1,9 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
Kernel.load(File.join(Rails.root, 'lib/api.rb'))
|
4
|
+
|
1
5
|
class APIController < ApplicationController
|
6
|
+
|
2
7
|
layout false
|
3
8
|
|
4
9
|
skip_before_filter :verify_authenticity_token
|
@@ -22,38 +27,35 @@ protected
|
|
22
27
|
end
|
23
28
|
|
24
29
|
def respond_with(object, options = {})
|
25
|
-
json = json_for(object)
|
30
|
+
json = Dao.json_for(object)
|
26
31
|
|
27
32
|
status = object.status rescue (options[:status] || 200)
|
28
33
|
status = status.code if status.respond_to?(:code)
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def json_for(object)
|
38
|
-
begin
|
39
|
-
if Rails.env.production?
|
40
|
-
::JSON.generate(object)
|
41
|
-
else
|
42
|
-
::JSON.pretty_generate(object, :max_nesting => 0)
|
35
|
+
if @format == 'json'
|
36
|
+
render(:json => json, :status => status)
|
37
|
+
else
|
38
|
+
respond_to do |wants|
|
39
|
+
wants.json{ render :json => json, :status => status }
|
40
|
+
wants.html{ render :text => json, :status => status, :content_type => 'text/plain' }
|
41
|
+
wants.xml{ render :text => 'no soup for you!', :status => 403 }
|
43
42
|
end
|
44
|
-
rescue Object => e
|
45
|
-
Rails.logger.error(e)
|
46
|
-
YAML.load( object.to_yaml ).to_json
|
47
43
|
end
|
48
44
|
end
|
49
45
|
|
50
46
|
def setup_path
|
51
47
|
@path = params[:path] || params[:action] || 'index'
|
52
|
-
|
48
|
+
@path, @format = @path.split(/\./, 2)
|
49
|
+
unless @format.blank?
|
50
|
+
params[:format] = @format
|
51
|
+
params[:path] = @path
|
52
|
+
end
|
53
|
+
unless api.route?(@path) or @path == 'index'
|
53
54
|
render :nothing => true, :status => 404
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
58
|
+
|
57
59
|
def setup_mode
|
58
60
|
@mode = params['mode'] || (request.get? ? 'read' : 'write')
|
59
61
|
end
|
@@ -87,13 +89,13 @@ protected
|
|
87
89
|
return
|
88
90
|
end
|
89
91
|
else
|
90
|
-
|
92
|
+
begin
|
91
93
|
if current_user
|
92
94
|
@api = Api.new(current_user)
|
93
95
|
else
|
94
96
|
render(:nothing => true, :status => :unauthorized)
|
95
97
|
end
|
96
|
-
|
98
|
+
rescue NameError
|
97
99
|
@api = Api.new
|
98
100
|
end
|
99
101
|
end
|
@@ -1,64 +1,70 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
<%
|
2
3
|
|
3
4
|
class_name = @conducer_name.camelize
|
4
5
|
model_name = class_name.sub(/Conducer/, '')
|
5
6
|
|
6
7
|
-%>
|
8
|
+
|
7
9
|
class <%= class_name %> < Dao::Conducer
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def all(params = {})
|
12
|
-
records = <%= model_name %>.paginate(params)
|
13
|
-
|
14
|
-
records.map! do |record|
|
15
|
-
new(record.attributes)
|
16
|
-
end
|
17
|
-
end
|
10
|
+
def initialize(user, model, params = {})
|
11
|
+
@user = user
|
12
|
+
@model = model
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
update_attributes(
|
15
|
+
:user => @user.attributes,
|
16
|
+
:model => @model.attributes,
|
17
|
+
|
18
|
+
:foo => 'bar'
|
19
|
+
)
|
20
|
+
|
21
|
+
id!(@model.id) unless @model.new_record?
|
22
|
+
|
23
|
+
mount(Dao::Upload, :logo, :placeholder => (@model.logo.try(:url) || 'http://placeholder.com/image.png'))
|
24
|
+
|
25
|
+
case action
|
26
|
+
when 'new', 'create'
|
27
|
+
@attributes.email = @user.email
|
28
|
+
@model.field = @page.field
|
29
|
+
|
30
|
+
update_attributes(params)
|
31
|
+
|
32
|
+
when 'edit', 'update', 'show'
|
33
|
+
@attributes.email = @user.email
|
34
|
+
@model.field = @page.field
|
25
35
|
|
26
|
-
|
27
|
-
#
|
28
|
-
def initialize
|
29
|
-
run_callbacks :initialize do
|
36
|
+
update_attributes(params)
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
40
|
+
|
41
|
+
validates_presence_of :something
|
42
|
+
|
33
43
|
def save
|
34
|
-
|
35
|
-
return(false) unless valid?
|
44
|
+
return(false) unless valid?
|
36
45
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
raise NotImplementedError, <<-__
|
47
|
+
this needs to
|
48
|
+
- persist data to the db and get a new id
|
49
|
+
- set the id on the object : @attributes.set(:id => id)
|
50
|
+
- return true or false
|
51
|
+
__
|
43
52
|
|
44
|
-
|
45
|
-
end
|
53
|
+
true
|
46
54
|
end
|
47
55
|
|
48
56
|
def destroy
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
id
|
57
|
+
id = self.id
|
58
|
+
if id
|
59
|
+
|
60
|
+
raise NotImplementedError, <<-__
|
61
|
+
this needs to
|
62
|
+
- un-persist data from the db
|
63
|
+
- set the id on the object to nil : @attributes.rm(:id)
|
64
|
+
- return this id of the destroyed object
|
65
|
+
__
|
66
|
+
|
62
67
|
end
|
68
|
+
id
|
63
69
|
end
|
64
70
|
end
|
@@ -1,27 +1,28 @@
|
|
1
1
|
/* dao errors */
|
2
|
-
table.dao.errors {
|
3
|
-
font-weight: normal;
|
4
|
-
width: 100%;
|
5
|
-
border-bottom: 1px solid #ccc;
|
6
|
-
}
|
7
|
-
table.dao.errors caption {
|
8
|
-
font-weight: bold;
|
9
|
-
color: #333;
|
10
|
-
font-style: italic;
|
11
|
-
text-align: left;
|
12
|
-
margin-bottom: 0.5em;
|
13
|
-
}
|
14
|
-
table.dao.errors td.key {
|
15
|
-
padding-left: 1em;
|
16
|
-
color: #666;
|
17
|
-
}
|
18
|
-
table.dao.errors td.separator {
|
19
|
-
color: #666;
|
20
|
-
padding-left: 0.5em;
|
21
|
-
padding-right: 0.5em;
|
22
|
-
}
|
23
|
-
table.dao.errors td.message {
|
24
|
-
font-style: italic;
|
25
|
-
width: 100%;
|
26
|
-
}
|
27
2
|
|
3
|
+
.dao.errors {
|
4
|
+
font-weight: normal;
|
5
|
+
width: 100%;
|
6
|
+
border-bottom: 1px solid #ccc;
|
7
|
+
background-color: #ffe;
|
8
|
+
padding: 0.5em;
|
9
|
+
}
|
10
|
+
|
11
|
+
.dao.errors .caption {
|
12
|
+
font-weight: bold;
|
13
|
+
color: #333;
|
14
|
+
font-style: italic;
|
15
|
+
text-align: left;
|
16
|
+
margin-bottom: 0.5em;
|
17
|
+
}
|
18
|
+
|
19
|
+
.dao.errors .title {
|
20
|
+
padding-left: 1em;
|
21
|
+
color: #666;
|
22
|
+
}
|
23
|
+
|
24
|
+
.dao.errors .message {
|
25
|
+
font-style: italic;
|
26
|
+
font-weight: bold;
|
27
|
+
width: 100%;
|
28
|
+
}
|
@@ -1,65 +1,40 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module DaoHelper
|
2
|
-
def render_dao(result, *args, &block)
|
3
|
-
if result.status =~ 200 or result.status == 420
|
4
|
-
@result = result unless defined?(@result)
|
5
|
-
render(*args, &block)
|
6
|
-
else
|
7
|
-
result.error!
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def dao(path, *args, &block)
|
12
|
-
options = args.extract_options!.to_options!
|
13
|
-
|
14
|
-
mode = options[:mode]
|
15
|
-
|
16
|
-
if mode.blank?
|
17
|
-
mode =
|
18
|
-
case request.method
|
19
|
-
when "GET"
|
20
|
-
:read
|
21
|
-
when "PUT", "POST", "DELETE"
|
22
|
-
:write
|
23
|
-
else
|
24
|
-
:read
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
@dao = api.send(mode, path, params)
|
29
|
-
@dao.route = request.fullpath
|
30
|
-
#@dao.mode = mode
|
31
|
-
|
32
|
-
#unless options[:error!] == false
|
33
|
-
@dao.error! unless @dao.status.ok?
|
34
|
-
#end
|
35
|
-
|
36
|
-
block ? block.call(@dao) : @dao
|
37
|
-
end
|
38
|
-
|
39
3
|
def dao_form_for(*args, &block)
|
40
4
|
options = args.extract_options!.to_options!
|
41
5
|
|
42
|
-
model = args.flatten.
|
6
|
+
model = args.flatten.detect{|arg| arg.respond_to?(:persisted?)}
|
43
7
|
|
44
8
|
if model
|
45
|
-
first = args.
|
46
|
-
url = options.delete(:url)
|
9
|
+
first = args.shift
|
10
|
+
url = args.shift || options.delete(:url)
|
11
|
+
|
47
12
|
method = options.delete(:method)
|
48
13
|
html = dao_form_attrs(options)
|
49
14
|
|
50
15
|
options.clear
|
51
16
|
|
52
|
-
if model.
|
53
|
-
url ||= url_for(first)
|
54
|
-
method ||= :post
|
55
|
-
else
|
56
|
-
url ||= url_for(first)
|
17
|
+
if model.persisted?
|
57
18
|
method ||= :put
|
19
|
+
else
|
20
|
+
method ||= :post
|
58
21
|
end
|
59
22
|
|
23
|
+
url =
|
24
|
+
case method
|
25
|
+
when :put
|
26
|
+
url_for(:action => :update)
|
27
|
+
when :post
|
28
|
+
url_for(:action => :create)
|
29
|
+
else
|
30
|
+
'./'
|
31
|
+
end
|
32
|
+
|
60
33
|
options[:url] = url
|
61
34
|
options[:html] = html.dup.merge(:method => method)
|
35
|
+
#options[:builder] = Dao::Form::Builder
|
62
36
|
|
37
|
+
args.push(model)
|
63
38
|
args.push(options)
|
64
39
|
|
65
40
|
form_for(*args) do
|
@@ -72,6 +47,8 @@ module DaoHelper
|
|
72
47
|
end
|
73
48
|
end
|
74
49
|
|
50
|
+
alias_method(:dao_form, :dao_form_for)
|
51
|
+
|
75
52
|
def dao_form_attrs(*args)
|
76
53
|
args.flatten!
|
77
54
|
options = args.extract_options!.to_options!.dup
|
@@ -87,5 +64,41 @@ module DaoHelper
|
|
87
64
|
options
|
88
65
|
end
|
89
66
|
|
67
|
+
def render_dao(result, *args, &block)
|
68
|
+
if result.status =~ 200 or result.status == 420
|
69
|
+
@result = result unless defined?(@result)
|
70
|
+
render(*args, &block)
|
71
|
+
else
|
72
|
+
result.error!
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def dao(path, *args, &block)
|
77
|
+
options = args.extract_options!.to_options!
|
78
|
+
|
79
|
+
mode = options[:mode]
|
80
|
+
|
81
|
+
if mode.blank?
|
82
|
+
mode =
|
83
|
+
case request.method
|
84
|
+
when "GET"
|
85
|
+
:read
|
86
|
+
when "PUT", "POST", "DELETE"
|
87
|
+
:write
|
88
|
+
else
|
89
|
+
:read
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
@dao = api.send(mode, path, params)
|
94
|
+
@dao.route = request.fullpath
|
95
|
+
#@dao.mode = mode
|
96
|
+
|
97
|
+
#unless options[:error!] == false
|
98
|
+
@dao.error! unless @dao.status.ok?
|
99
|
+
#end
|
100
|
+
|
101
|
+
block ? block.call(@dao) : @dao
|
102
|
+
end
|
90
103
|
end
|
91
104
|
ApplicationController.send(:include, DaoHelper)
|