dima-ruboss4ruby 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +2 -2
- data/Manifest.txt +9 -3
- data/README.rdoc +43 -15
- data/Rakefile +9 -4
- data/app_generators/ruboss_app/USAGE +11 -2
- data/app_generators/ruboss_app/ruboss_app_generator.rb +21 -15
- data/app_generators/ruboss_app/templates/app.yaml.erb +12 -0
- data/app_generators/ruboss_app/templates/default_tasks.rake +1 -1
- data/app_generators/ruboss_app/templates/empty.txt +0 -0
- data/app_generators/ruboss_app/templates/generate.rb +1 -5
- data/app_generators/ruboss_app/templates/index.yaml +11 -0
- data/app_generators/ruboss_app/templates/mainair-app.xml +1 -1
- data/bin/ruboss-gen +18 -4
- data/generators/ruboss_config/ruboss_config_generator.rb +0 -5
- data/generators/ruboss_controller/ruboss_controller_generator.rb +15 -10
- data/generators/ruboss_controller/templates/assist.py +65 -0
- data/generators/ruboss_controller/templates/restful.py +136 -0
- data/generators/ruboss_main_app/ruboss_main_app_generator.rb +18 -4
- data/generators/ruboss_main_app/templates/main.py.erb +29 -0
- data/generators/ruboss_main_app/templates/mainapp.mxml +5 -1
- data/generators/ruboss_scaffold/ruboss_scaffold_generator.rb +77 -46
- data/generators/ruboss_scaffold/templates/controller.py.erb +27 -0
- data/generators/ruboss_scaffold/templates/model.as.erb +1 -1
- data/generators/ruboss_scaffold/templates/model.py.erb +14 -0
- data/generators/ruboss_yaml_scaffold/USAGE +42 -4
- data/generators/ruboss_yaml_scaffold/ruboss_yaml_scaffold_generator.rb +8 -4
- data/lib/ruboss4ruby.rb +15 -2
- data/lib/ruboss4ruby/active_foo.rb +32 -3
- data/lib/ruboss4ruby/active_record_default_methods.rb +19 -7
- data/lib/ruboss4ruby/active_record_tasks.rb +9 -3
- data/lib/ruboss4ruby/configuration.rb +32 -0
- data/lib/ruboss4ruby/datamapper_foo.rb +6 -0
- data/lib/ruboss4ruby/rails/recipes.rb +5 -3
- data/lib/ruboss4ruby/rails/swf_helper.rb +1 -0
- data/lib/ruboss4ruby/tasks.rb +5 -0
- data/rails_generators/ruboss_config/ruboss_config_generator.rb +14 -13
- data/rails_generators/ruboss_config/templates/mainair-app.xml +1 -1
- data/rails_generators/ruboss_config/templates/ruboss_tasks.rake +1 -0
- data/rails_generators/ruboss_controller/ruboss_controller_generator.rb +2 -5
- data/rails_generators/ruboss_scaffold/ruboss_scaffold_generator.rb +66 -62
- data/rails_generators/ruboss_scaffold/templates/model.as.erb +1 -1
- data/rails_generators/ruboss_yaml_scaffold/USAGE +38 -1
- data/rails_generators/ruboss_yaml_scaffold/ruboss_yaml_scaffold_generator.rb +0 -5
- data/rcl-1.0.txt +0 -0
- data/rdoc/generators/template/html/jamis.rb +588 -0
- data/ruboss4ruby.gemspec +12 -12
- metadata +15 -26
@@ -0,0 +1,136 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2008 William T. Katz
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to
|
7
|
+
# deal in the Software without restriction, including without limitation
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
"""
|
24
|
+
RESTful Controller
|
25
|
+
|
26
|
+
We want our RESTful controllers to simply throw up their hands if they get
|
27
|
+
an unhandled HTTP verb. This is better for rich clients and server load
|
28
|
+
than throwing back lots of useless HTML.
|
29
|
+
|
30
|
+
These inherited methods should be overridden if there's a chance a human
|
31
|
+
browser is involved.
|
32
|
+
|
33
|
+
TODO: Return more information HTTP status codes that won't autotrip
|
34
|
+
browser login forms. For example, return status 405 (Method not allowed)
|
35
|
+
with an Allow header containing the list of valid methods.
|
36
|
+
"""
|
37
|
+
__author__ = 'William T. Katz'
|
38
|
+
|
39
|
+
from google.appengine.ext import webapp
|
40
|
+
|
41
|
+
import logging
|
42
|
+
|
43
|
+
# Some useful module methods
|
44
|
+
def send_successful_response(handler, response):
|
45
|
+
logging.debug("Sending successful response: %s", response)
|
46
|
+
handler.response.headers["Content-Type"] = "application/xml"
|
47
|
+
handler.response.out.write('<?xml version="1.0" encoding="UTF-8"?>')
|
48
|
+
handler.response.out.write(response)
|
49
|
+
|
50
|
+
def get_model_key(handler):
|
51
|
+
return handler.request.path_info.split("/").pop().replace(".xml", "")
|
52
|
+
|
53
|
+
def get_sent_properties(request_func, propname_list):
|
54
|
+
"""
|
55
|
+
This maps request strings to values in a hash, optionally run through
|
56
|
+
a function with previous request values as parameters to the func.
|
57
|
+
1) key -> just read in the corresponding request value
|
58
|
+
2) tuple (key, func) -> Read the request value for the string key
|
59
|
+
and pass it through func
|
60
|
+
3) tuple (key, func, additional keys...) -> Get the request
|
61
|
+
values for the additional keys and pass them through func
|
62
|
+
before setting the key's value with the output.
|
63
|
+
If a key is not present in the request, then we do not insert a key
|
64
|
+
with None or empty string. The key is simply absent, therefore allowing
|
65
|
+
you to use the returned hash to initial a Model instance.
|
66
|
+
"""
|
67
|
+
prop_hash = {}
|
68
|
+
for item in propname_list:
|
69
|
+
if isinstance(item, basestring):
|
70
|
+
key = item
|
71
|
+
value = request_func(item)
|
72
|
+
elif isinstance(item, tuple):
|
73
|
+
key = item[0]
|
74
|
+
prop_func = item[1]
|
75
|
+
if len(item) <= 2:
|
76
|
+
value = prop_func(request_func(key))
|
77
|
+
else:
|
78
|
+
try:
|
79
|
+
addl_keys = map(prop_hash.get, item[2:])
|
80
|
+
value = prop_func(*addl_keys)
|
81
|
+
except:
|
82
|
+
return None
|
83
|
+
if value:
|
84
|
+
prop_hash[key] = value
|
85
|
+
return prop_hash
|
86
|
+
|
87
|
+
def methods_via_query_allowed(handler_method):
|
88
|
+
"""
|
89
|
+
A decorator to automatically re-route overloaded POSTs
|
90
|
+
that specify the real HTTP method in a _method query string.
|
91
|
+
|
92
|
+
To use it, decorate your post method like this:
|
93
|
+
|
94
|
+
import restful
|
95
|
+
...
|
96
|
+
@restful.methods_via_query_allowed
|
97
|
+
def post(self):
|
98
|
+
pass
|
99
|
+
|
100
|
+
The decorator will check for a _method query string or POST argument,
|
101
|
+
and if present, will redirect to delete(), put(), etc.
|
102
|
+
"""
|
103
|
+
def redirect_if_needed(self, *args, **kwargs):
|
104
|
+
real_verb = self.request.get('_method', None)
|
105
|
+
if not real_verb and 'X-HTTP-Method-Override' in self.request.environ:
|
106
|
+
real_verb = self.request.environ['X-HTTP-Method-Override']
|
107
|
+
if real_verb:
|
108
|
+
logging.debug("Redirected from POST. Detected method override = %s", real_verb)
|
109
|
+
method = real_verb.upper()
|
110
|
+
if method == 'HEAD':
|
111
|
+
self.head(*args, **kwargs)
|
112
|
+
elif method == 'PUT':
|
113
|
+
self.put(*args, **kwargs)
|
114
|
+
elif method == 'DELETE':
|
115
|
+
self.delete(*args, **kwargs)
|
116
|
+
elif method == 'TRACE':
|
117
|
+
self.trace(*args, **kwargs)
|
118
|
+
elif method == 'OPTIONS':
|
119
|
+
self.head(*args, **kwargs)
|
120
|
+
# POST and GET included for completeness
|
121
|
+
elif method == 'POST':
|
122
|
+
self.post(*args, **kwargs)
|
123
|
+
elif method == 'GET':
|
124
|
+
self.get(*args, **kwargs)
|
125
|
+
else:
|
126
|
+
self.error(405)
|
127
|
+
else:
|
128
|
+
handler_method(self, *args, **kwargs)
|
129
|
+
return redirect_if_needed
|
130
|
+
|
131
|
+
class Controller(webapp.RequestHandler):
|
132
|
+
def get(self, *params):
|
133
|
+
self.redirect("/403.html")
|
134
|
+
|
135
|
+
def head(self, *params):
|
136
|
+
pass
|
@@ -7,9 +7,10 @@ class RubossMainAppGenerator < RubiGen::Base
|
|
7
7
|
:base_folder,
|
8
8
|
:command_controller_name,
|
9
9
|
:model_names,
|
10
|
-
:command_names,
|
11
10
|
:component_names,
|
11
|
+
:controller_names,
|
12
12
|
:use_air,
|
13
|
+
:use_gae,
|
13
14
|
:application_tag
|
14
15
|
|
15
16
|
def initialize(runtime_args, runtime_options = {})
|
@@ -31,16 +32,29 @@ class RubossMainAppGenerator < RubiGen::Base
|
|
31
32
|
if File.exists?("app/flex/#{base_folder}/components/generated")
|
32
33
|
@component_names = list_mxml_files("app/flex/#{base_folder}/components/generated")
|
33
34
|
end
|
35
|
+
|
36
|
+
@controller_names = []
|
37
|
+
if options[:gae] && File.exists?("app/controllers")
|
38
|
+
@use_gae = true
|
39
|
+
@controller_names =
|
40
|
+
Dir.entries("app/controllers").grep(/\.py$/).delete_if { |name| name == "__init__.py" || name == "restful.py" }.map { |name| name.sub(/\.py$/, "") }
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
44
|
def manifest
|
37
45
|
record do |m|
|
38
46
|
m.template 'mainapp.mxml', File.join('app', 'flex', "#{project_name}.mxml")
|
47
|
+
if options[:gae]
|
48
|
+
m.template 'main.py.erb', 'main.py'
|
49
|
+
end
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
53
|
protected
|
43
|
-
|
44
|
-
|
45
|
-
|
54
|
+
def add_options!(opt)
|
55
|
+
opt.separator ''
|
56
|
+
opt.separator 'Options:'
|
57
|
+
opt.on("--gae", "Generate Google App Engine Python classes in addition to Ruboss Flex resources.",
|
58
|
+
"Default: false") { |v| options[:gae] = v }
|
59
|
+
end
|
46
60
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
import logging
|
4
|
+
import wsgiref.handlers
|
5
|
+
|
6
|
+
from google.appengine.api import users
|
7
|
+
from google.appengine.ext import webapp
|
8
|
+
from google.appengine.ext.webapp.util import run_wsgi_app
|
9
|
+
from app.controllers import <%= controller_names.join(", ") %>
|
10
|
+
|
11
|
+
class AppController(webapp.RequestHandler):
|
12
|
+
def get(self):
|
13
|
+
self.redirect("/public/index.html")
|
14
|
+
|
15
|
+
def main():
|
16
|
+
application = webapp.WSGIApplication(
|
17
|
+
[('/*$', AppController),
|
18
|
+
<% for component in controller_names -%>
|
19
|
+
<% if component == controller_names.last -%>
|
20
|
+
('/<%= component %>.*', <%= component %>.Controller)
|
21
|
+
<% else -%>
|
22
|
+
('/<%= component %>.*', <%= component %>.Controller),
|
23
|
+
<% end -%>
|
24
|
+
<% end -%>
|
25
|
+
], debug=True)
|
26
|
+
wsgiref.handlers.CGIHandler().run(application)
|
27
|
+
|
28
|
+
if __name__ == '__main__':
|
29
|
+
main()
|
@@ -8,12 +8,16 @@
|
|
8
8
|
<% if use_air -%>
|
9
9
|
import org.ruboss.services.air.AIRServiceProvider;
|
10
10
|
<% end -%>
|
11
|
-
|
11
|
+
<% if use_gae -%>
|
12
|
+
import org.ruboss.services.http.GAEHTTPServiceProvider;
|
13
|
+
<% end -%>
|
12
14
|
import <%= base_package %>.controllers.<%= command_controller_name %>;
|
13
15
|
|
14
16
|
private function init():void {
|
15
17
|
<% if use_air -%>
|
16
18
|
<%= command_controller_name %>.initialize([AIRServiceProvider], AIRServiceProvider.ID, "<%= base_package %>");
|
19
|
+
<% elsif use_gae -%>
|
20
|
+
<%= command_controller_name %>.initialize([GAEHTTPServiceProvider], GAEHTTPServiceProvider.ID);
|
17
21
|
<% else -%>
|
18
22
|
<%= command_controller_name %>.initialize();
|
19
23
|
<% end -%>
|
@@ -10,22 +10,48 @@ module Ruboss4Ruby
|
|
10
10
|
|
11
11
|
def flex_type
|
12
12
|
@flex_type = case type
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
when :integer then 'int'
|
14
|
+
when :date, :datetime, :time then 'Date'
|
15
|
+
when :boolean then 'Boolean'
|
16
|
+
when :float, :decimal then 'Number'
|
17
|
+
else
|
18
|
+
'String'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def flex_default
|
22
|
+
def flex_default
|
23
23
|
@flex_default = case type
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
when :integer then '0'
|
25
|
+
when :date, :datetime, :time then 'new Date'
|
26
|
+
when :boolean then 'false'
|
27
|
+
when :float, :decimal then 'new Number'
|
28
|
+
else
|
29
|
+
"\"\""
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def gae_type
|
34
|
+
@gae_type = case type
|
35
|
+
when :integer then 'IntegerProperty'
|
36
|
+
when :date then 'DateProperty'
|
37
|
+
when :time then 'TimeProperty'
|
38
|
+
when :datetime then 'DateTimeProperty'
|
39
|
+
when :boolean then 'BooleanProperty'
|
40
|
+
when :text then 'TextProperty'
|
41
|
+
when :float, :decimal then 'FloatProperty'
|
42
|
+
else
|
43
|
+
'StringProperty'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def gae_default
|
48
|
+
@gae_default = case type
|
49
|
+
when :integer then 'default = 0'
|
50
|
+
when :date, :time, :datetime then 'auto_now_add = True'
|
51
|
+
when :boolean then 'default = False'
|
52
|
+
when :float, :decimal then 'default = 0.0'
|
53
|
+
else
|
54
|
+
""
|
29
55
|
end
|
30
56
|
end
|
31
57
|
end
|
@@ -48,9 +74,7 @@ class RubossScaffoldGenerator < RubiGen::Base
|
|
48
74
|
attr_reader :name,
|
49
75
|
:class_name,
|
50
76
|
:file_name
|
51
|
-
|
52
|
-
attr_accessor :constructor_args
|
53
|
-
|
77
|
+
|
54
78
|
def initialize(runtime_args, runtime_options = {})
|
55
79
|
super
|
56
80
|
|
@@ -62,8 +86,34 @@ class RubossScaffoldGenerator < RubiGen::Base
|
|
62
86
|
@file_name = @name.underscore
|
63
87
|
@class_name = @name.camelize
|
64
88
|
|
65
|
-
@project_name, @flex_project_name, @command_controller_name,
|
66
|
-
|
89
|
+
@project_name, @flex_project_name, @command_controller_name,
|
90
|
+
@base_package, @base_folder = extract_names
|
91
|
+
extract_relationships
|
92
|
+
end
|
93
|
+
|
94
|
+
def manifest
|
95
|
+
record do |m|
|
96
|
+
m.template 'model.as.erb',
|
97
|
+
File.join("app", 'flex', base_folder, "models", "#{@class_name}.as"),
|
98
|
+
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
99
|
+
|
100
|
+
m.template 'component.mxml.erb',
|
101
|
+
File.join("app", 'flex', base_folder, "components", "generated", "#{@class_name}Box.mxml"),
|
102
|
+
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
103
|
+
|
104
|
+
if options[:gae]
|
105
|
+
m.template 'controller.py.erb', "app/controllers/#{file_name.pluralize}.py"
|
106
|
+
m.template 'model.py.erb', "app/models/#{file_name}.py"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Run the rcontroller generator to clobber the
|
110
|
+
# RubossCommandController subclass to include the new models.
|
111
|
+
m.dependency 'ruboss_controller', [name] + @args, :collision => :force, :gae => options[:gae]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
protected
|
116
|
+
def extract_relationships
|
67
117
|
@belongs_tos = []
|
68
118
|
@has_ones = []
|
69
119
|
@has_manies = []
|
@@ -80,38 +130,19 @@ class RubossScaffoldGenerator < RubiGen::Base
|
|
80
130
|
end
|
81
131
|
end
|
82
132
|
|
83
|
-
# Remove the has_one and has_many arguments since they are
|
84
|
-
# not for consumption by the scaffold generator, and since
|
85
|
-
# we have already used them to set the @belongs_tos, @has_ones and
|
86
|
-
# @has_manies.
|
87
133
|
@args.delete_if { |elt| elt =~ /^(has_one|has_many|belongs_to):/ }
|
88
134
|
end
|
89
|
-
|
90
|
-
def manifest
|
91
|
-
record do |m|
|
92
|
-
# Generate Flex AS model and MXML component based on the
|
93
|
-
# Ruboss templates.
|
94
|
-
|
95
|
-
puts @file_name
|
96
|
-
|
97
|
-
m.template 'model.as.erb',
|
98
|
-
File.join("app", 'flex', base_folder, "models", "#{@class_name}.as"),
|
99
|
-
:assigns => { :resource_controller_name => "#{file_name.pluralize}" }
|
100
135
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# Run the rcontroller generator to clobber the
|
106
|
-
# RubossCommandController subclass to include the new models.
|
107
|
-
m.dependency 'ruboss_controller', [name] + @args, :collision => :force
|
136
|
+
def attributes
|
137
|
+
@attributes ||= @args.collect do |attribute|
|
138
|
+
Ruboss4Ruby::Generator::GeneratedAttribute.new(*attribute.split(":"))
|
108
139
|
end
|
109
140
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
141
|
+
|
142
|
+
def add_options!(opt)
|
143
|
+
opt.separator ''
|
144
|
+
opt.separator 'Options:'
|
145
|
+
opt.on("--gae", "Generate Google App Engine Python classes in addition to Ruboss Flex resources.",
|
146
|
+
"Default: false") { |v| options[:gae] = v }
|
147
|
+
end
|
117
148
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import restful
|
2
|
+
import logging
|
3
|
+
|
4
|
+
from google.appengine.ext import webapp
|
5
|
+
from google.appengine.api import users
|
6
|
+
from google.appengine.ext import db
|
7
|
+
from app.models import assist, <%= file_name %>
|
8
|
+
|
9
|
+
class Controller(restful.Controller):
|
10
|
+
def get(self):
|
11
|
+
restful.send_successful_response(self, assist.all(<%= file_name %>.<%= class_name %>))
|
12
|
+
|
13
|
+
@restful.methods_via_query_allowed
|
14
|
+
def post(self):
|
15
|
+
model = <%= file_name %>.<%= class_name %>()
|
16
|
+
assist.update_model_from_params(model, self.request.params)
|
17
|
+
restful.send_successful_response(self, model.to_xml())
|
18
|
+
|
19
|
+
def put(self):
|
20
|
+
model = <%= file_name %>.<%= class_name %>.get(db.Key(restful.get_model_key(self)))
|
21
|
+
assist.update_model_from_params(model, self.request.params)
|
22
|
+
restful.send_successful_response(self, model.to_xml())
|
23
|
+
|
24
|
+
def delete(self):
|
25
|
+
model = <%= file_name %>.<%= class_name %>.get(db.Key(restful.get_model_key(self)))
|
26
|
+
db.delete(model)
|
27
|
+
restful.send_successful_response(self, model.to_xml())
|
@@ -17,7 +17,7 @@ package <%= base_package %>.models {
|
|
17
17
|
<% if attribute.type == :datetime || attribute.type == :time -%>
|
18
18
|
[DateTime]
|
19
19
|
<% end -%>
|
20
|
-
public var <%= attribute.flex_name %>:<%= attribute.flex_type %>;
|
20
|
+
public var <%= attribute.flex_name %>:<%= attribute.flex_type %> = <%= attribute.flex_default %>;
|
21
21
|
|
22
22
|
<% end -%>
|
23
23
|
<% for model in belongs_tos -%>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from google.appengine.ext import db
|
2
|
+
<% if belongs_tos.length > 0 -%>
|
3
|
+
import <%= belongs_tos.join(", ") %>
|
4
|
+
<% end -%>
|
5
|
+
|
6
|
+
class <%= class_name %>(db.Model):
|
7
|
+
<% for attribute in attributes -%>
|
8
|
+
<%= attribute.name %> = db.<%= attribute.gae_type %>(<%= attribute.gae_default %>)
|
9
|
+
<% end -%>
|
10
|
+
<% for model in belongs_tos -%>
|
11
|
+
<%= model %> = db.ReferenceProperty(<%= model %>.<%= model.camelcase %>)
|
12
|
+
<% end -%>
|
13
|
+
|
14
|
+
|
@@ -1,7 +1,45 @@
|
|
1
1
|
Description:
|
2
|
-
Scaffolds an entire application based on db/model.yml file.
|
3
|
-
|
4
|
-
|
2
|
+
Scaffolds an entire application based on db/model.yml file.
|
3
|
+
|
4
|
+
This generator transforms entries in db/model.yml into
|
5
|
+
command line calls to "ruboss_scaffold".
|
5
6
|
|
6
7
|
Examples:
|
7
|
-
`./script/generate ruboss_yaml_scaffold`
|
8
|
+
`./script/generate ruboss_yaml_scaffold`
|
9
|
+
|
10
|
+
Sample Model File:
|
11
|
+
project:
|
12
|
+
- name: string
|
13
|
+
- notes: text
|
14
|
+
- start_date: date
|
15
|
+
- end_date: date
|
16
|
+
- completed: boolean
|
17
|
+
- belongs_to: [user]
|
18
|
+
- has_many: [tasks]
|
19
|
+
|
20
|
+
location:
|
21
|
+
- name: string
|
22
|
+
- notes: text
|
23
|
+
- belongs_to: [user]
|
24
|
+
- has_many: [tasks]
|
25
|
+
|
26
|
+
task:
|
27
|
+
- name: string
|
28
|
+
- notes: text
|
29
|
+
- start_time: datetime
|
30
|
+
- end_time: datetime
|
31
|
+
- completed: boolean
|
32
|
+
- next_action: boolean
|
33
|
+
- belongs_to: [project, location, user]
|
34
|
+
|
35
|
+
note:
|
36
|
+
- content: text
|
37
|
+
- belongs_to: [user]
|
38
|
+
|
39
|
+
user:
|
40
|
+
- login: string
|
41
|
+
- first_name: string
|
42
|
+
- last_name: string
|
43
|
+
- email: string
|
44
|
+
- has_many: [tasks, projects, locations]
|
45
|
+
- has_one: [note]
|