ajax_grid_generator 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/USAGE ADDED
@@ -0,0 +1,30 @@
1
+ Description:
2
+ The Ajax_grid generator generates a fully functional, ajax based CRUD
3
+ grid for a given table. It is based heavily on the scaffold generator.
4
+ The generated code, with only some css help, is usable as is for CRUD
5
+ operations on a single table.
6
+
7
+ Like it's scaffolding forbearer, ajax_grid takes a model name, an
8
+ optional controller name, and a list of views as arguments. Scaffolded
9
+ actions and views are created automatically. Any views left over
10
+ generate empty stubs.
11
+
12
+ The scaffolded actions and views are:
13
+ index, list, show, new, create, edit, update, destroy
14
+
15
+ All of these, except index are implemented as partials to be rendered
16
+ in updateable divs on the client.
17
+
18
+ If a controller name is not given, the plural form of the model name
19
+ will be used. The model and controller names may be given in CamelCase
20
+ or under_score and should not be suffixed with 'Model' or 'Controller'.
21
+ Both model and controller names may be prefixed with a module like a
22
+ file path; see the Modules Example for usage.
23
+
24
+ Example:
25
+ ./script/generate ajax_grid product
26
+
27
+ This will generate a Product model and ProductController with a full test
28
+ suite and an ajax user interface.
29
+
30
+
@@ -0,0 +1,202 @@
1
+ class ScaffoldingSandbox
2
+ include ActionView::Helpers::ActiveRecordHelper
3
+
4
+ attr_accessor :form_action, :singular_name, :suffix, :model_instance
5
+
6
+ def sandbox_binding
7
+ binding
8
+ end
9
+
10
+ def default_input_block
11
+ Proc.new { |record, column|
12
+ size=column.limit ? column.limit : 10
13
+ size=10 if size<10
14
+ "<div class=\"#{column.name}\">#{input(record, column.name, :size => size)}</div>"
15
+ }
16
+ end
17
+
18
+ end
19
+
20
+ class ActionView::Helpers::InstanceTag
21
+ def to_input_field_tag(field_type, options={})
22
+ field_meth = "#{field_type}_field"
23
+ "<%= #{field_meth} '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+options.inspect} %>"
24
+ end
25
+
26
+ def to_text_area_tag(options = {})
27
+ "<%= text_area '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
28
+ end
29
+
30
+ def to_date_select_tag(options = {})
31
+ "<%= date_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
32
+ end
33
+
34
+ def to_datetime_select_tag(options = {})
35
+ "<%= datetime_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
36
+ end
37
+ end
38
+
39
+ class AjaxGridGenerator < Rails::Generator::NamedBase
40
+ attr_reader :controller_name,
41
+ :controller_class_path,
42
+ :controller_file_path,
43
+ :controller_class_nesting,
44
+ :controller_class_nesting_depth,
45
+ :controller_class_name,
46
+ :controller_singular_name,
47
+ :controller_plural_name
48
+ alias_method :controller_file_name, :controller_singular_name
49
+ alias_method :controller_table_name, :controller_plural_name
50
+
51
+ def initialize(runtime_args, runtime_options = {})
52
+ super
53
+
54
+ # Take controller name from the next argument. Default to the pluralized model name.
55
+ @controller_name = args.shift
56
+ @controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name
57
+
58
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
59
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
60
+
61
+ if @controller_class_nesting.empty?
62
+ @controller_class_name = @controller_class_name_without_nesting
63
+ else
64
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
65
+ end
66
+ end
67
+
68
+ def manifest
69
+ record do |m|
70
+ # Check for class naming collisions.
71
+ m.class_collisions controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper"
72
+
73
+ # Controller, helper, views, and test directories.
74
+ m.directory File.join('app/controllers', controller_class_path)
75
+ m.directory File.join('app/helpers', controller_class_path)
76
+ m.directory File.join('app/views', controller_class_path, controller_file_name)
77
+ m.directory File.join('test/functional', controller_class_path)
78
+
79
+ # Depend on model generator but skip if the model exists.
80
+ m.dependency 'model', [singular_name], :collision => :skip
81
+
82
+ # Scaffolded forms.
83
+ m.complex_template "form.rhtml",
84
+ File.join('app/views',
85
+ controller_class_path,
86
+ controller_file_name,
87
+ "_form.rhtml"),
88
+ :insert => 'form_scaffolding.rhtml',
89
+ :sandbox => lambda { create_sandbox },
90
+ :begin_mark => 'form',
91
+ :end_mark => 'eoform',
92
+ :mark_id => singular_name
93
+
94
+ # Stylsheet
95
+ m.template 'style.css', 'public/stylesheets/ajax_grid.css'
96
+ m.template 'controller_specific.css', "public/stylesheets/#{@plural_name}.css"
97
+
98
+ # Scaffolded views.
99
+ scaffold_views.each do |action|
100
+ m.template "view_#{action}.rhtml",
101
+ File.join('app/views',
102
+ controller_class_path,
103
+ controller_file_name,
104
+ "#{action}.rhtml"),
105
+ :assigns => { :action => action }
106
+ end
107
+ # Scaffolded partials.
108
+ scaffold_partials.each do |action|
109
+ m.template "view_#{action}.rhtml",
110
+ File.join('app/views',
111
+ controller_class_path,
112
+ controller_file_name,
113
+ "_#{action}.rhtml"),
114
+ :assigns => { :action => action }
115
+ end
116
+
117
+ # Controller class, functional test, helper, and views.
118
+ m.template 'controller.rb',
119
+ File.join('app/controllers',
120
+ controller_class_path,
121
+ "#{controller_file_name}_controller.rb")
122
+
123
+ m.template 'functional_test.rb',
124
+ File.join('test/functional',
125
+ controller_class_path,
126
+ "#{controller_file_name}_controller_test.rb")
127
+
128
+ m.template 'helper.rb',
129
+ File.join('app/helpers',
130
+ controller_class_path,
131
+ "#{controller_file_name}_helper.rb")
132
+
133
+ # Layout
134
+ m.template 'layout.rhtml', "app/views/layouts/#{controller_file_name}.rhtml"
135
+
136
+
137
+ # Unscaffolded views.
138
+ unscaffolded_actions.each do |action|
139
+ path = File.join('app/views',
140
+ controller_class_path,
141
+ controller_file_name,
142
+ "#{action}.rhtml")
143
+ m.template "controller:view.rhtml", path,
144
+ :assigns => { :action => action, :path => path}
145
+ end
146
+ end
147
+ end
148
+
149
+ protected
150
+ # Override with your own usage banner.
151
+ def banner
152
+ "Usage: #{$0} scaffold ModelName [ControllerName] [action, ...]"
153
+ end
154
+
155
+ def scaffold_views
156
+ %w(index)
157
+ end
158
+ def scaffold_partials
159
+ %w(list item new edit)
160
+ end
161
+
162
+ def scaffold_actions
163
+ scaffold_views + scaffold_partials + %w(create update destroy)
164
+ end
165
+
166
+ def model_name
167
+ class_name.demodulize
168
+ end
169
+
170
+ def unscaffolded_actions
171
+ args - scaffold_actions
172
+ end
173
+
174
+ def suffix
175
+ "_#{singular_name}" if options[:suffix]
176
+ end
177
+
178
+ def create_sandbox
179
+ sandbox = ScaffoldingSandbox.new
180
+ sandbox.singular_name = singular_name
181
+ begin
182
+ sandbox.model_instance = model_instance
183
+ sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance)
184
+ rescue ActiveRecord::StatementInvalid => e
185
+ logger.error "Before updating scaffolding from new DB schema, try creating a table for your model (#{class_name})"
186
+ raise SystemExit
187
+ end
188
+ sandbox.suffix = suffix
189
+ sandbox
190
+ end
191
+
192
+ def model_instance
193
+ base = class_nesting.split('::').inject(Object) do |base, nested|
194
+ break base.const_get(nested) if base.const_defined?(nested)
195
+ base.const_set(nested, Module.new)
196
+ end
197
+ unless base.const_defined?(@class_name_without_nesting)
198
+ base.const_set(@class_name_without_nesting, Class.new(ActiveRecord::Base))
199
+ end
200
+ class_name.constantize.new
201
+ end
202
+ end
@@ -0,0 +1,54 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ paginate :<%= plural_name %>, :per_page => 10
3
+ <% unless suffix -%>
4
+ def index
5
+ end
6
+ <% end -%>
7
+
8
+ <% for action in unscaffolded_actions -%>
9
+ def <%= action %><%= suffix %>
10
+ end
11
+
12
+ <% end -%>
13
+ def list<%= suffix %>
14
+ render :partial => 'list'
15
+ end
16
+
17
+ def show<%= suffix %>
18
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
19
+ render :partial =>'item'
20
+ end
21
+
22
+ def new<%= suffix %>
23
+ @<%= singular_name %> = <%= model_name %>.new
24
+ render :partial => 'new'
25
+ end
26
+
27
+ def create<%= suffix %>
28
+ @<%= singular_name %> = <%= model_name %>.new(params[:<%= singular_name %>])
29
+ if @<%= singular_name %>.save
30
+ list
31
+ else
32
+ render :partial => 'new'
33
+ end
34
+ end
35
+
36
+ def edit<%= suffix %>
37
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
38
+ render :partial => 'edit'
39
+ end
40
+
41
+ def update
42
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
43
+ if @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
44
+ render :partial => 'item'
45
+ else
46
+ render :partial => 'edit'
47
+ end
48
+ end
49
+
50
+ def destroy<%= suffix %>
51
+ <%= model_name %>.find(params[:id]).destroy
52
+ render :nothing => true
53
+ end
54
+ end
@@ -0,0 +1,12 @@
1
+ #<%= controller_name %> { border: solid 1px #000; height: 27em; margin: 2ex; padding: 2ex; position: relative;}
2
+
3
+ .<%= singular_name %> { clear: both; position:relative;}
4
+ .<%= singular_name %> a {display: block}
5
+ .<%= singular_name %> div, #headers div, .<%= singular_name %> a { float:left; padding: 1ex; }
6
+
7
+ <% model_instance.class.content_columns.each do |column|
8
+ size=column.limit ? column.limit : 10
9
+ size=10 if size<10
10
+ size *=1.5 %>
11
+ .<%= column.name %> {width: <%= size %>ex;}
12
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%%= error_messages_for '<%= singular_name %>' %>
2
+
3
+ <%= template_for_inclusion %>
@@ -0,0 +1 @@
1
+ <%= all_input_tags(@model_instance, @singular_name, {}) %>
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '<%= "/.." * controller_class_nesting_depth %>/../test_helper'
2
+ require '<%= controller_file_path %>_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
6
+
7
+ class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
8
+ fixtures :<%= table_name %>
9
+
10
+ def setup
11
+ @controller = <%= controller_class_name %>Controller.new
12
+ @request = ActionController::TestRequest.new
13
+ @response = ActionController::TestResponse.new
14
+ end
15
+
16
+ <% for action in unscaffolded_actions -%>
17
+ def test_<%= action %>
18
+ get :<%= action %>
19
+ assert_response :success
20
+ assert_template '<%= action %>'
21
+ end
22
+
23
+ <% end -%>
24
+ <% unless suffix -%>
25
+ def test_index
26
+ get :index
27
+ assert_response :success
28
+ assert_template 'list'
29
+ end
30
+
31
+ <% end -%>
32
+ def test_list<%= suffix %>
33
+ get :list<%= suffix %>
34
+
35
+ assert_response :success
36
+ assert_template 'list<%= suffix %>'
37
+
38
+ assert_not_nil assigns(:<%= plural_name %>)
39
+ end
40
+
41
+ def test_show<%= suffix %>
42
+ get :show<%= suffix %>, :id => 1
43
+
44
+ assert_response :success
45
+ assert_template 'show'
46
+
47
+ assert_not_nil assigns(:<%= singular_name %>)
48
+ assert assigns(:<%= singular_name %>).valid?
49
+ end
50
+
51
+ def test_new<%= suffix %>
52
+ get :new<%= suffix %>
53
+
54
+ assert_response :success
55
+ assert_template 'new<%= suffix %>'
56
+
57
+ assert_not_nil assigns(:<%= singular_name %>)
58
+ end
59
+
60
+ def test_create
61
+ num_<%= plural_name %> = <%= model_name %>.count
62
+
63
+ post :create<%= suffix %>, :<%= singular_name %> => {}
64
+
65
+ assert_response :redirect
66
+ assert_redirected_to :action => 'list<%= suffix %>'
67
+
68
+ assert_equal num_<%= plural_name %> + 1, <%= model_name %>.count
69
+ end
70
+
71
+ def test_edit<%= suffix %>
72
+ get :edit<%= suffix %>, :id => 1
73
+
74
+ assert_response :success
75
+ assert_template 'edit<%= suffix %>'
76
+
77
+ assert_not_nil assigns(:<%= singular_name %>)
78
+ assert assigns(:<%= singular_name %>).valid?
79
+ end
80
+
81
+ def test_update<%= suffix %>
82
+ post :update<%= suffix %>, :id => 1
83
+ assert_response :redirect
84
+ assert_redirected_to :action => 'show<%= suffix %>', :id => 1
85
+ end
86
+
87
+ def test_destroy<%= suffix %>
88
+ assert_not_nil <%= model_name %>.find(1)
89
+
90
+ post :destroy, :id => 1
91
+ assert_response :redirect
92
+ assert_redirected_to :action => 'list<%= suffix %>'
93
+
94
+ assert_raise(ActiveRecord::RecordNotFound) {
95
+ <%= model_name %>.find(1)
96
+ }
97
+ end
98
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,26 @@
1
+ <html>
2
+ <head>
3
+ <title><%= model_name %> Management</title>
4
+ <%%= javascript_include_tag "prototype" %>
5
+ <%%= javascript_include_tag "effects" %>
6
+ <%%= stylesheet_link_tag 'ajax_grid' %>
7
+ <%%= stylesheet_link_tag '<%= plural_name %>' %>
8
+ </head>
9
+ <body>
10
+
11
+ <%%= link_to_remote "New <%= singular_name %>",
12
+ {:update => '<%=controller_name%>',
13
+ :url => {:action => 'new'},
14
+ :complete => "new Effect.Appear('<%= controller_name %>')"} %>
15
+ <div id="headers">
16
+ <%% for column in <%=model_name %>.content_columns %>
17
+ <div class="<%%= column.name -%>"><%%= column.human_name -%></div>
18
+ <%% end %>
19
+ </div>
20
+
21
+ <div id="<%= controller_name %>">
22
+ <%%= @content_for_layout %>
23
+ </div>
24
+
25
+ </body>
26
+ </html>
@@ -0,0 +1,81 @@
1
+ body {
2
+ background-color: #fff; color: #000;
3
+ font-family: verdana, arial, helvetica, sans-serif;
4
+ font-size: 16px;
5
+ line-height: 18px;
6
+ }
7
+
8
+ #headers { font-weight:bold; height: 1em; text-decoration: underline;margin: 2ex; padding: 2ex;}
9
+
10
+ #navlinks {text-align:center; position:absolute; bottom:0;padding: 2ex;width:100%;}
11
+
12
+ body, p, ol, ul, td {
13
+ }
14
+
15
+ pre {
16
+ background-color: #eee;
17
+ padding: 10px;
18
+ font-size: 11px;
19
+ }
20
+
21
+ a { color: #000; }
22
+ a:visited { color: #666; }
23
+ a:hover { color: #fff; background-color:#000; }
24
+
25
+ .fieldWithErrors {
26
+ background-color: red;
27
+ }
28
+
29
+ #ErrorExplanation {
30
+ position:absolute;
31
+ top: 3em;
32
+ z-index:100;
33
+ width: 400px;
34
+ border: 2px solid red;
35
+ padding: 7px;
36
+ padding-bottom: 12px;
37
+ margin-bottom: 20px;
38
+ background-color: #f0f0f0;
39
+ }
40
+
41
+ #ErrorExplanation h2 {
42
+ text-align: left;
43
+ font-weight: bold;
44
+ padding: 5px 5px 5px 15px;
45
+ font-size: 12px;
46
+ margin: -7px;
47
+ background-color: #c00;
48
+ color: #fff;
49
+ }
50
+
51
+ #ErrorExplanation p {
52
+ color: #333;
53
+ margin-bottom: 0;
54
+ padding: 5px;
55
+ }
56
+
57
+ #ErrorExplanation ul li {
58
+ font-size: 12px;
59
+ list-style: square;
60
+ }
61
+
62
+ div.uploadStatus {
63
+ margin: 5px;
64
+ }
65
+
66
+ div.progressBar {
67
+ margin: 5px;
68
+ }
69
+
70
+ div.progressBar div.border {
71
+ background-color: #fff;
72
+ border: 1px solid grey;
73
+ width: 100%;
74
+ }
75
+
76
+ div.progressBar div.background {
77
+ background-color: #333;
78
+ height: 18px;
79
+ width: 0%;
80
+ }
81
+
@@ -0,0 +1,14 @@
1
+
2
+ <%%= form_remote_tag :update => @<%= singular_name %>.id,
3
+ :url => {:action => 'update', :id => @<%= singular_name %>},
4
+ :loading => "new Effect.Fade(#{@<%= singular_name %>.id})",
5
+ :complete => "new Effect.Appear(#{@<%= singular_name %>.id})" %>
6
+
7
+ <%%= render :partial => 'form' %>
8
+ <div class="ctlSave"><%%= submit_tag 'save'%></div>
9
+ <%%= link_to_remote 'Cancel',
10
+ :update=>@<%= singular_name %>.id,
11
+ :url => {:action => 'show', :id => @<%= singular_name %>},
12
+ :loading => "new Effect.Fade(#{@<%= singular_name %>.id})",
13
+ :complete => "new Effect.Appear(#{@<%= singular_name %>.id})" %>
14
+ <%%= end_form_tag %>
@@ -0,0 +1 @@
1
+ <%%= render :partial => 'list' %>
@@ -0,0 +1,15 @@
1
+ <%% for column in <%= model_name -%>.content_columns %>
2
+ <div class="<%%= column.name -%>"><%%=h @<%= singular_name -%>.send(column.name) -%></div>
3
+ <%% end %>
4
+ <%%= link_to_remote 'Edit',
5
+ {:update => @<%= singular_name %>.id,
6
+ :url => {:action => 'edit', :id => @<%= singular_name -%> },
7
+ :loading => "new Effect.Fade(#{@<%= singular_name -%>.id})",
8
+ :complete => "new Effect.Appear(#{@<%= singular_name -%>.id})"},
9
+ :class => 'edit_link' %>
10
+ <%%= link_to_remote 'Destroy',
11
+ {:update => @<%= singular_name %>.id,
12
+ :url => {:action => 'destroy', :id => @<%= singular_name -%> },
13
+ :confirm => 'Are you sure?',
14
+ :complete => "new Effect.Puff(#{@<%= singular_name %>.id})"},
15
+ :class => 'destroy_link' %>
@@ -0,0 +1,19 @@
1
+ <%% for @<%= singular_name %> in @<%= controller_name %> %>
2
+ <div class="<%= singular_name %>" id="<%%= @<%= singular_name -%>.id -%>">
3
+ <%%= render :partial => 'item' %>
4
+ </div>
5
+ <%% end %>
6
+
7
+ <div id='navLinks'>
8
+ <%%= link_to_remote 'Previous page',
9
+ { :update=>'<%= controller_name %>',
10
+ :url=>{:action => 'list', :page => @<%= singular_name %>_pages.current.previous },
11
+ :complete => "new Effect.Appear ('<%= controller_name %>')"},
12
+ :class => 'navLink' if @<%= singular_name %>_pages.current.previous %>
13
+ <%%= link_to_remote 'Next page',
14
+ { :update=>'<%= controller_name %>',
15
+ :url=>{:action => 'list', :page => @<%= singular_name %>_pages.current.next },
16
+ :complete => "new Effect.Appear ('<%= controller_name %>')"},
17
+ :class => 'navLink' if @<%= singular_name %>_pages.current.next %>
18
+ </div>
19
+
@@ -0,0 +1,7 @@
1
+ <div class="<%= singular_name -%> edit" id="<%%= @<%= singular_name %>.id %>">
2
+ <%%= form_remote_tag :update => '<%= controller_name %>', :url => {:action => 'create'} %>
3
+ <%%= render :partial => 'form' %>
4
+ <div class="ctlSave"><%%= submit_tag "Create" %></div>
5
+ <%%= link_to_remote 'Cancel', :update=>'<%= controller_name %>', :url => {:action => 'list'} %>
6
+ <%%= end_form_tag %>
7
+ </div>
metadata ADDED
@@ -0,0 +1,67 @@
1
+ !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: ajax_grid_generator
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.5.0
7
+ date: 2006-01-15 00:00:00 +00:00
8
+ summary: "[Rails] Ajax Grid generator."
9
+ require_paths:
10
+ - .
11
+ email: evronm@dtcinc.net
12
+ homepage: http://www.rubyonrails.org/show/Generators
13
+ rubyforge_project:
14
+ description: Generates Rails code implementing an Ajax based CRUD grid for a single table.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - Michael Evron
30
+ files:
31
+ - USAGE
32
+ - ajax_grid_generator.rb
33
+ - templates/controller.rb
34
+ - templates/controller_specific.css
35
+ - templates/form.rhtml
36
+ - templates/form_scaffolding.rhtml
37
+ - templates/functional_test.rb
38
+ - templates/helper.rb
39
+ - templates/layout.rhtml
40
+ - templates/style.css
41
+ - templates/view_edit.rhtml
42
+ - templates/view_index.rhtml
43
+ - templates/view_item.rhtml
44
+ - templates/view_list.rhtml
45
+ - templates/view_new.rhtml
46
+ test_files: []
47
+
48
+ rdoc_options: []
49
+
50
+ extra_rdoc_files: []
51
+
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ requirements: []
57
+
58
+ dependencies:
59
+ - !ruby/object:Gem::Dependency
60
+ name: rails
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Version::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 0.10.0
67
+ version: