trestle_generator 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/USAGE ADDED
@@ -0,0 +1,35 @@
1
+ Description:
2
+ The trestle generator (an adaptation of the Rails scaffold generator)
3
+ creates a controller to interact with a model. If the model does not exist,
4
+ it creates the model as well. The generated code is equivalent to the
5
+ "scaffold :model" declaration, making it easy to migrate when you wish to
6
+ customize your controller and views.
7
+
8
+ The generator takes a model name, an optional controller name, and a
9
+ list of views as arguments. Trestled actions and views are created
10
+ automatically. Any views left over generate empty stubs.
11
+
12
+ The trestled actions are:
13
+ index, new, edit, destroy
14
+
15
+ The trestled views are:
16
+ _index_without_id, _index_with_id, new, edit
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 trestle Account Bank debit credit
26
+
27
+ This will generate an Account model and BankController with a full test
28
+ suite and a basic user interface. Now create the accounts table in your
29
+ database and browse to http://localhost/bank/ -- voila, you're on Rails!
30
+
31
+ Modules Example:
32
+ ./script/generate trestle CreditCard 'admin/credit_card' suspend late_fee
33
+
34
+ This will generate a CreditCard model and CreditCardController controller
35
+ in the admin module.
@@ -0,0 +1,56 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ verify :only => [ :edit<%= suffix %>, :destroy<%= suffix %> ],
3
+ :params => :id,
4
+ :add_flash => { :notice => 'Missing <%= singular_name %> ID.' },
5
+ :redirect_to => { :action => '<%= suffix || 'index' %>' }
6
+
7
+ <% for action in untrestled_actions -%>
8
+ def <%= action %><%= suffix %>
9
+ end
10
+
11
+ <% end -%>
12
+ def destroy<%= suffix %>
13
+ if request.post?
14
+ <%= model_name %>.find(params[:id]).destroy
15
+ flash[:notice] = 'The <%= singular_name %> was successfully destroyed.'
16
+ redirect_to :action => '<%= suffix || 'index' %>'
17
+ else
18
+ flash[:notice] = 'Click Destroy to destroy the <%= model_name %>.'
19
+ redirect_to :action => 'edit<%= suffix %>', :id => params[:id]
20
+ end
21
+ end
22
+
23
+ def edit<%= suffix %>
24
+ if request.post?
25
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
26
+ if @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
27
+ flash[:notice] = 'The <%= singular_name %> was successfully edited.'
28
+ redirect_to :action => '<%= suffix || 'index' %>', :id => @<%= singular_name %>
29
+ end
30
+ else
31
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
32
+ end
33
+ end
34
+
35
+ def <%= suffix || 'index' %>
36
+ if params[:id]
37
+ @<%= singular_name %> = <%= model_name %>.find(params[:id])
38
+ render '<%= plural_name %>/_<%= suffix || 'index' %>_with_id'
39
+ else
40
+ @<%= singular_name %>_pages, @<%= plural_name %> = paginate(:<%= plural_name %>)
41
+ render '<%= plural_name %>/_<%= suffix || 'index' %>_without_id'
42
+ end
43
+ end
44
+
45
+ def new<%= suffix %>
46
+ if request.post?
47
+ @<%= singular_name %> = <%= model_name %>.new(params[:<%= singular_name %>])
48
+ if @<%= singular_name %>.save
49
+ flash[:notice] = 'A new <%= singular_name %> was successfully added.'
50
+ redirect_to :action => '<%= suffix || 'index' %>'
51
+ end
52
+ else
53
+ @<%= singular_name %> = <%= model_name %>.new
54
+ end
55
+ end
56
+ 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,104 @@
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 untrestled_actions -%>
17
+ def test_<%= action %>
18
+ get :<%= action %>
19
+ assert_response :success
20
+ assert_template '<%= action %>'
21
+ end
22
+
23
+ <% end -%>
24
+ def test_<%= suffix || 'index' %>
25
+ get :<%= suffix || 'index' %>
26
+ assert_response :success
27
+ assert_template '<%= plural_name %>/_<%= suffix || 'index' %>_without_id'
28
+ end
29
+
30
+ def test_destroy<%= suffix %>_using_get
31
+ assert_not_nil <%= model_name %>.find(1)
32
+
33
+ get :destroy<%= suffix %>, :id => 1
34
+ assert_response :redirect
35
+ assert_redirected_to :action => 'edit<%= suffix %>'
36
+
37
+ assert_not_nil <%= model_name %>.find(1)
38
+ end
39
+
40
+ def test_destroy<%= suffix %>_using_post
41
+ assert_not_nil <%= model_name %>.find(1)
42
+
43
+ post :destroy<%= suffix %>, :id => 1
44
+ assert_response :redirect
45
+ assert_redirected_to :action => '<%= suffix || 'index' %>'
46
+
47
+ assert_raise(ActiveRecord::RecordNotFound) { <%= model_name %>.find(1) }
48
+ end
49
+
50
+ def test_edit<%= suffix %>_using_get
51
+ get :edit<%= suffix %>, :id => 1
52
+
53
+ assert_response :success
54
+ assert_template 'edit<%= suffix %>'
55
+
56
+ assert_not_nil assigns(:<%= singular_name %>)
57
+ assert assigns(:<%= singular_name %>).valid?
58
+ end
59
+
60
+ def test_edit<%= suffix %>_using_post
61
+ post :edit<%= suffix %>, :id => 1
62
+ assert_response :redirect
63
+ assert_redirected_to :action => '<%= suffix || 'index' %>', :id => 1
64
+ end
65
+
66
+ def test_<%= suffix || 'index' %>_without_id
67
+ get :<%= suffix || 'index' %>
68
+
69
+ assert_response :success
70
+ assert_template '<%= plural_name %>/_<%= suffix || 'index' %>_without_id'
71
+
72
+ assert_not_nil assigns(:<%= plural_name %>)
73
+ end
74
+
75
+ def test_<%= suffix || 'index' %>_with_id
76
+ get :<%= suffix || 'index' %>, :id => 1
77
+
78
+ assert_response :success
79
+ assert_template '<%= plural_name %>/_<%= suffix || 'index' %>_with_id'
80
+
81
+ assert_not_nil assigns(:<%= singular_name %>)
82
+ assert assigns(:<%= singular_name %>).valid?
83
+ end
84
+
85
+ def test_new<%= suffix %>_using_get
86
+ get :new<%= suffix %>
87
+
88
+ assert_response :success
89
+ assert_template 'new<%= suffix %>'
90
+
91
+ assert_not_nil assigns(:<%= singular_name %>)
92
+ end
93
+
94
+ def test_new<%= suffix %>_using_post
95
+ num_<%= plural_name %> = <%= model_name %>.count
96
+
97
+ post :new<%= suffix %>, :<%= singular_name %> => {}
98
+
99
+ assert_response :redirect
100
+ assert_redirected_to :action => '<%= suffix || 'index' %>'
101
+
102
+ assert_equal num_<%= plural_name %> + 1, <%= model_name %>.count
103
+ end
104
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,13 @@
1
+ <html>
2
+ <head>
3
+ <title><%= controller_class_name %>: <%%= controller.action_name %></title>
4
+ <%%= stylesheet_link_tag 'trestle' %>
5
+ </head>
6
+ <body>
7
+
8
+ <p style="color: green"><%%= flash[:notice] %></p>
9
+
10
+ <%%= @content_for_layout %>
11
+
12
+ </body>
13
+ </html>
@@ -0,0 +1,21 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ # Add your own custom routes here.
3
+ # The priority is based upon order of creation: first created -> highest priority.
4
+
5
+ # Here's a sample route:
6
+ # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7
+ # Keep in mind you can assign values other than :controller and :action
8
+
9
+ # You can have the root of your site routed by hooking up ''
10
+ # -- just remember to delete public/index.html.
11
+ # map.connect '', :controller => "welcome"
12
+
13
+ # Allow downloading Web Service WSDL as a file with an extension
14
+ # instead of a file named 'wsdl'
15
+ map.connect ':controller/service.wsdl', :action => 'wsdl'
16
+
17
+ # Install the default route as the lowest priority.
18
+ map.connect ':controller/:action', :action => 'index', :requirements => { :action => /[^\d]+/ }
19
+ map.connect ':controller/:id', :action => 'index', :requirements => { :id => /[\d]+/ }
20
+ map.connect ':controller/:id/:action'
21
+ end
@@ -0,0 +1,74 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ .fieldWithErrors {
20
+ padding: 2px;
21
+ background-color: red;
22
+ display: table;
23
+ }
24
+
25
+ #ErrorExplanation {
26
+ width: 400px;
27
+ border: 2px solid red;
28
+ padding: 7px;
29
+ padding-bottom: 12px;
30
+ margin-bottom: 20px;
31
+ background-color: #f0f0f0;
32
+ }
33
+
34
+ #ErrorExplanation h2 {
35
+ text-align: left;
36
+ font-weight: bold;
37
+ padding: 5px 5px 5px 15px;
38
+ font-size: 12px;
39
+ margin: -7px;
40
+ background-color: #c00;
41
+ color: #fff;
42
+ }
43
+
44
+ #ErrorExplanation p {
45
+ color: #333;
46
+ margin-bottom: 0;
47
+ padding: 5px;
48
+ }
49
+
50
+ #ErrorExplanation ul li {
51
+ font-size: 12px;
52
+ list-style: square;
53
+ }
54
+
55
+ div.uploadStatus {
56
+ margin: 5px;
57
+ }
58
+
59
+ div.progressBar {
60
+ margin: 5px;
61
+ }
62
+
63
+ div.progressBar div.border {
64
+ background-color: #fff;
65
+ border: 1px solid grey;
66
+ width: 100%;
67
+ }
68
+
69
+ div.progressBar div.background {
70
+ background-color: #333;
71
+ height: 18px;
72
+ width: 0%;
73
+ }
74
+
@@ -0,0 +1,8 @@
1
+ <%% for column in <%= model_name %>.content_columns %>
2
+ <p>
3
+ <b><%%= column.human_name %>:</b> <%%= h @<%= singular_name %>.send(column.name) %>
4
+ </p>
5
+ <%% end %>
6
+
7
+ <%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => @<%= singular_name %> %> |
8
+ <%%= link_to 'Back to list', :action => '<%= suffix || 'index' %>' %>
@@ -0,0 +1,27 @@
1
+ <h1>Listing <%= plural_name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <%% for column in <%= model_name %>.content_columns %>
6
+ <th><%%= column.human_name %></th>
7
+ <%% end %>
8
+ </tr>
9
+
10
+ <%% for <%= singular_name %> in @<%= plural_name %> %>
11
+ <tr>
12
+ <%% for column in <%= model_name %>.content_columns %>
13
+ <td><%%=h <%= singular_name %>.send(column.name) %></td>
14
+ <%% end %>
15
+ <td><%%= link_to 'Show', :action => '<%= suffix || 'index' %>', :id => <%= singular_name %> %></td>
16
+ <td><%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => <%= singular_name %> %></td>
17
+ <td><%%= link_to 'Destroy', { :action => 'destroy<%= suffix %>', :id => <%= singular_name %> }, :post => true, :confirm => 'Are you sure you want to destroy this <%= singular_name %>?' %>
18
+ </tr>
19
+ <%% end %>
20
+ </table>
21
+
22
+ <%%= link_to 'Previous page', { :page => @<%= singular_name %>_pages.current.previous } if @<%= singular_name %>_pages.current.previous %>
23
+ <%%= link_to 'Next page', { :page => @<%= singular_name %>_pages.current.next } if @<%= singular_name %>_pages.current.next %>
24
+
25
+ <br />
26
+
27
+ <%%= link_to 'New <%= singular_name %>', :action => 'new<%= suffix %>' %>
@@ -0,0 +1,10 @@
1
+ <h1>Editing <%= singular_name %></h1>
2
+
3
+ <%%= start_form_tag :action => 'edit<%= @suffix %>', :id => @<%= singular_name %> %>
4
+ <%%= render :partial => 'form' %>
5
+ <%%= submit_tag 'Save' %>
6
+ <%%= end_form_tag %>
7
+ <%%= button_to 'Destroy', { :action => 'destroy<%= suffix %>', :id => @<%= singular_name %> }, :confirm => 'Are you sure you want to destroy this <%= singular_name %>?' %>
8
+
9
+ <%%= link_to 'Show', :action => '<%= suffix || 'index' %>', :id => @<%= singular_name %> %> |
10
+ <%%= link_to 'Back to list', :action => '<%= suffix || 'index' %>' %>
@@ -0,0 +1,8 @@
1
+ <h1>New <%= singular_name %></h1>
2
+
3
+ <%%= start_form_tag :action => 'new<%= @suffix %>' %>
4
+ <%%= render :partial => 'form' %>
5
+ <%%= submit_tag 'Save' %>
6
+ <%%= end_form_tag %>
7
+
8
+ <%%= link_to 'Back to list', :action => '<%= suffix || 'index' %>' %>
@@ -0,0 +1,188 @@
1
+ class TrestleSandbox
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| "<p><label for=\"#{record}_#{column.name}\">#{column.human_name}</label><br/>\n#{input(record, column.name)}</p>\n" }
12
+ end
13
+ end
14
+
15
+ class ActionView::Helpers::InstanceTag
16
+ def to_input_field_tag(field_type, options={})
17
+ field_meth = "#{field_type}_field"
18
+ "<%= #{field_meth} '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+options.inspect} %>"
19
+ end
20
+
21
+ def to_text_area_tag(options = {})
22
+ "<%= text_area '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
23
+ end
24
+
25
+ def to_date_select_tag(options = {})
26
+ "<%= date_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
27
+ end
28
+
29
+ def to_datetime_select_tag(options = {})
30
+ "<%= datetime_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
31
+ end
32
+ end
33
+
34
+ class TrestleGenerator < Rails::Generator::NamedBase
35
+ attr_reader :controller_name,
36
+ :controller_class_path,
37
+ :controller_file_path,
38
+ :controller_class_nesting,
39
+ :controller_class_nesting_depth,
40
+ :controller_class_name,
41
+ :controller_singular_name,
42
+ :controller_plural_name
43
+ alias_method :controller_file_name, :controller_singular_name
44
+ alias_method :controller_table_name, :controller_plural_name
45
+
46
+ def initialize(runtime_args, runtime_options = {})
47
+ super
48
+
49
+ # Take controller name from the next argument. Default to the pluralized model name.
50
+ @controller_name = args.shift
51
+ @controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name
52
+
53
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
54
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
55
+
56
+ if @controller_class_nesting.empty?
57
+ @controller_class_name = @controller_class_name_without_nesting
58
+ else
59
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
60
+ end
61
+ end
62
+
63
+ def manifest
64
+ record do |m|
65
+ # Check for class naming collisions.
66
+ m.class_collisions controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper"
67
+
68
+ # Controller, helper, views, test, and config directories.
69
+ m.directory File.join('app/controllers', controller_class_path)
70
+ m.directory File.join('app/helpers', controller_class_path)
71
+ m.directory File.join('app/views', controller_class_path, controller_file_name)
72
+ m.directory File.join('test/functional', controller_class_path)
73
+ m.directory File.join('config', controller_class_path)
74
+
75
+ # Depend on model generator but skip if the model exists.
76
+ m.dependency 'model', [singular_name], :collision => :skip
77
+
78
+ # Scaffolded forms.
79
+ m.complex_template "form.rhtml",
80
+ File.join('app/views',
81
+ controller_class_path,
82
+ controller_file_name,
83
+ "_form.rhtml"),
84
+ :insert => 'form_trestle.rhtml',
85
+ :sandbox => lambda { create_sandbox },
86
+ :begin_mark => 'form',
87
+ :end_mark => 'eoform',
88
+ :mark_id => singular_name
89
+
90
+ # Scaffolded views.
91
+ trestle_views.each do |action|
92
+ m.template "view_#{action}.rhtml",
93
+ File.join('app/views',
94
+ controller_class_path,
95
+ controller_file_name,
96
+ "#{action}.rhtml"),
97
+ :assigns => { :action => action }
98
+ end
99
+
100
+ # Controller class, functional test, helper, and views.
101
+ m.template 'controller.rb',
102
+ File.join('app/controllers',
103
+ controller_class_path,
104
+ "#{controller_file_name}_controller.rb")
105
+
106
+ m.template 'functional_test.rb',
107
+ File.join('test/functional',
108
+ controller_class_path,
109
+ "#{controller_file_name}_controller_test.rb")
110
+
111
+ m.template 'helper.rb',
112
+ File.join('app/helpers',
113
+ controller_class_path,
114
+ "#{controller_file_name}_helper.rb")
115
+
116
+ # Layout and stylesheet.
117
+ m.template 'layout.rhtml', "app/views/layouts/#{controller_file_name}.rhtml"
118
+ m.template 'style.css', 'public/stylesheets/trestle.css'
119
+
120
+
121
+ # Untrestled views.
122
+ untrestled_actions.each do |action|
123
+ path = File.join('app/views',
124
+ controller_class_path,
125
+ controller_file_name,
126
+ "#{action}.rhtml")
127
+ m.template "controller:view.rhtml", path,
128
+ :assigns => { :action => action, :path => path}
129
+ end
130
+
131
+ # Routes.
132
+ m.template 'routes.rb', 'config/routes.rb'
133
+ end
134
+ end
135
+
136
+
137
+ protected
138
+
139
+ # Override with your own usage banner.
140
+ def banner
141
+ "Usage: #{$0} trestle ModelName [ControllerName] [action, ...]"
142
+ end
143
+
144
+ def trestle_views
145
+ %w(edit _index_without_id _index_with_id new)
146
+ end
147
+
148
+ def trestle_actions
149
+ %w(destroy edit index new)
150
+ end
151
+
152
+ def model_name
153
+ class_name.demodulize
154
+ end
155
+
156
+ def untrestled_actions
157
+ args - trestle_actions
158
+ end
159
+
160
+ def suffix
161
+ "_#{singular_name}" if options[:suffix]
162
+ end
163
+
164
+ def create_sandbox
165
+ sandbox = TrestleSandbox.new
166
+ sandbox.singular_name = singular_name
167
+ begin
168
+ sandbox.model_instance = model_instance
169
+ sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance)
170
+ rescue ActiveRecord::StatementInvalid => e
171
+ logger.error "Before updating trestle from new DB schema, try creating a table for your model (#{class_name})"
172
+ raise SystemExit
173
+ end
174
+ sandbox.suffix = suffix
175
+ sandbox
176
+ end
177
+
178
+ def model_instance
179
+ base = class_nesting.split('::').inject(Object) do |base, nested|
180
+ break base.const_get(nested) if base.const_defined?(nested)
181
+ base.const_set(nested, Module.new)
182
+ end
183
+ unless base.const_defined?(@class_name_without_nesting)
184
+ base.const_set(@class_name_without_nesting, Class.new(ActiveRecord::Base))
185
+ end
186
+ class_name.constantize.new
187
+ end
188
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: trestle_generator
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2006-01-03
8
+ summary: "[Rails] An adaptation of the scaffold generator that produces production-ready
9
+ controllers that are safe from state-changing HTTP GET requests and that have
10
+ streamlined URLs."
11
+ require_paths:
12
+ - templates
13
+ email: nils@alumni.rice.edu
14
+ homepage: http://www.rubyforge.org/projects/trestle
15
+ rubyforge_project: trestle
16
+ description: "The name of this RubyGem points out that nobody intentionally sends a train
17
+ across a gorge with nothing but a scaffold to support it. That�s what a trestle
18
+ is for! Why use the trestle generator instead of the scaffold generator? The
19
+ trestle generator produces code that is closer to production-quality in two
20
+ respects: SAFETY The trestle generator uses the HTTP POST method for actions
21
+ that change data. Well-behaved web applications protect themselves against
22
+ errant HTTP GET requests (such as come from Google Web Accelerator and the
23
+ like). The scaffold generator fails to do this. USABILITY The trestle
24
+ generator produces controllers with just four actions (index, new, edit, and
25
+ destroy). Controllers produced by the scaffold generator have eight actions.
26
+ Fewer actions exposed to the outside world is better if the behavior of these
27
+ actions is in line with the semantics of HTTP GET and HTTP POST. The net effect
28
+ is that you will not have to throw away or tweak as much trestle-generated code
29
+ as you do scaffold-generated code. Less work for you means your application gets
30
+ built sooner. Tobias L�tke�s postback_generator RubyGem has the same idea. The
31
+ scaffold generator produces a controller with the following public interface for
32
+ a database table named �people�: /people - lists existing person records
33
+ /people/list - lists existing person records /people/new - shows an empty
34
+ person form /people/create - creates a new person record from request
35
+ parameters /people/show/99 - shows the person record having ID 99
36
+ /people/edit/99 - shows a person form for the person record having ID 99
37
+ /people/update/99 - updates the person record having ID 99 using request
38
+ parameters /people/destroy/99 - deletes the person record having ID 99, even
39
+ for HTTP GET! Contrast this with the public interface produced by the trestle
40
+ generator: /people - lists existing person records /people/new - HTTP GET
41
+ shows an empty person form; HTTP POST creates a new person record from request
42
+ parameters /people/99 - shows the person record having ID 99 /people/99/edit -
43
+ HTTP GET shows a person form for the person record having ID 99; HTTP POST
44
+ updates the person record having ID 99 using request parameters
45
+ /people/99/destroy - HTTP GET redirects to /people/99/edit with a notice that
46
+ the user must click the form�s Destroy button to destroy a record; HTTP POST
47
+ deletes the person record having ID 99 after prompting the user for confirmation
48
+ Notice the hierarchical nature of trestle URLs. Because the ID comes before the
49
+ verb, there are fewer illegal variations that with scaffold URLs. This
50
+ encourages the user to use the Up One Level button on the Google Toolbar that
51
+ clips one element off the end of the current URL. Scaffold URLs do not play
52
+ nicely with the Up One Level button."
53
+ autorequire:
54
+ default_executable:
55
+ bindir: bin
56
+ has_rdoc: false
57
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
58
+ requirements:
59
+ -
60
+ - ">"
61
+ - !ruby/object:Gem::Version
62
+ version: 0.0.0
63
+ version:
64
+ platform: ruby
65
+ authors:
66
+ - Nils Jonsson
67
+ files:
68
+ - trestle_generator.rb
69
+ - USAGE
70
+ - templates/controller.rb
71
+ - templates/form.rhtml
72
+ - templates/form_trestle.rhtml
73
+ - templates/functional_test.rb
74
+ - templates/helper.rb
75
+ - templates/layout.rhtml
76
+ - templates/routes.rb
77
+ - templates/style.css
78
+ - templates/view_edit.rhtml
79
+ - templates/view_new.rhtml
80
+ - templates/view__index_without_id.rhtml
81
+ - templates/view__index_with_id.rhtml
82
+ test_files: []
83
+ rdoc_options: []
84
+ extra_rdoc_files: []
85
+ executables: []
86
+ extensions: []
87
+ requirements:
88
+ - Ruby on Rails v1.0.0
89
+ dependencies:
90
+ - !ruby/object:Gem::Dependency
91
+ name: rails
92
+ version_requirement:
93
+ version_requirements: !ruby/object:Gem::Version::Requirement
94
+ requirements:
95
+ -
96
+ - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.0.0
99
+ version: