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,5 +1,5 @@
1
1
  Description:
2
- rails generate dao system
2
+ rails generate dao system|conducer
3
3
 
4
4
  Example:
5
- rails generate dao system
5
+ rails generate dao system|conducer
@@ -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
- dao_dir = File.join(Rails.root, 'app/dao')
34
+ FileUtils.mkdir_p(File.join(Rails.root, 'app/conducers'))
47
35
 
48
- FileUtils.mkdir_p(dao_dir)
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", "public/javascripts/dao.js")
58
- copy_file("dao.css", "public/stylesheets/dao.css")
42
+ copy_file("dao.js", "app/assets/javascripts/dao.js")
59
43
 
60
- route("match 'api(/*path)' => 'api#index', :as => 'api'")
44
+ copy_file("dao.css", "app/assets/stylesheets/dao.css")
61
45
 
62
- gem("yajl-ruby")
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 'app/dao/api.rb'
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.id
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
- respond_to do |wants|
31
- wants.json{ render :json => json, :status => status }
32
- wants.html{ render :text => json, :status => status, :content_type => 'text/plain' }
33
- wants.xml{ render :text => 'no soup for you!', :status => 403 }
34
- end
35
- end
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
- unless api.route?(@path) or @path=='index'
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
- if defined?(current_user)
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
- else
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
- ## class_methods
9
- #
10
- class << <%= class_name %>
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
- def find(id)
20
- raise NotImplementedError, <<-__
21
- this needs to return an instance based on the id
22
- __
23
- end
24
- end
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
- ## instance_methods
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
- run_callbacks :save do
35
- return(false) unless valid?
44
+ return(false) unless valid?
36
45
 
37
- raise NotImplementedError, <<-__
38
- this needs to
39
- - persist data to the db and get a new id
40
- - set the id on the object : @attributes.set(:id => id)
41
- - return true or false
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
- true
45
- end
53
+ true
46
54
  end
47
55
 
48
56
  def destroy
49
- run_callbacks :destroy do
50
- id = self.id
51
- if id
52
-
53
- raise NotImplementedError, <<-__
54
- this needs to
55
- - un-persist data from the db
56
- - set the id on the object to nil : @attributes.rm(:id)
57
- - return this id of the destroyed object
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
+ }
@@ -109,6 +109,9 @@ if(!window.Dao){
109
109
  };
110
110
  })();
111
111
  }
112
+
113
+ // short-cuts for read and write
114
+ //
112
115
  Dao.Api.prototype['read'] = Dao.Api.prototype['get'];
113
116
  Dao.Api.prototype['write'] = Dao.Api.prototype['post'];
114
117
 
@@ -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.select{|arg| arg.respond_to?(:new_record?)}.last
6
+ model = args.flatten.detect{|arg| arg.respond_to?(:persisted?)}
43
7
 
44
8
  if model
45
- first = args.first
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.new_record?
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)