ajax_grid_generator 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: