nested_restful_scaffold 0.1.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.
@@ -0,0 +1,19 @@
1
+ README
2
+ Rakefile
3
+ generators/nested_restful_scaffold/USAGE
4
+ generators/nested_restful_scaffold/nested_restful_scaffold_generator.rb
5
+ generators/nested_restful_scaffold/templates/controller.rb
6
+ generators/nested_restful_scaffold/templates/fixtures.yml
7
+ generators/nested_restful_scaffold/templates/functional_test.rb
8
+ generators/nested_restful_scaffold/templates/helper.rb
9
+ generators/nested_restful_scaffold/templates/layout.html.erb
10
+ generators/nested_restful_scaffold/templates/migration.rb
11
+ generators/nested_restful_scaffold/templates/model.rb
12
+ generators/nested_restful_scaffold/templates/style.css
13
+ generators/nested_restful_scaffold/templates/unit_test.rb
14
+ generators/nested_restful_scaffold/templates/view_edit.html.erb
15
+ generators/nested_restful_scaffold/templates/view_index.html.erb
16
+ generators/nested_restful_scaffold/templates/view_new.html.erb
17
+ generators/nested_restful_scaffold/templates/view_show.html.erb
18
+ nested_restful_scaffold.gemspec
19
+ Manifest
data/README ADDED
@@ -0,0 +1,92 @@
1
+ = Nested Restful Scaffold
2
+
3
+ == What is NestedRestfulScaffold
4
+ NestedRestfulScaffold is a gem built by BadrIT (http://www.badrit.com) for easily generating controller, views, model and routes of nested resources.
5
+
6
+ == Why NestedRestfulScaffold
7
+ The story begins when I was working on a project at BadrIT (http://www.badrit.com) using Ruby on Rails.
8
+ We needed to generate simple scaffold controller, views, models and routes for many nested resources.
9
+ There were a huge number of resources and nested resources and sometimes the length of nesting was more than two.
10
+ The problem I faced that I need to create them with rails scaffold generator then I need to update all generated controllers, views and models.
11
+ * I need to update routes.rb to handle nested paths like /libraries/1/books
12
+ * In the controller I need to be sure I am accessing the correct resource in the nested chain.
13
+ * All ActiveRecord calls in the controller must be scoped.
14
+ * Views will have a lot of work to support nested forms and links.
15
+ * Create the Active Record associations in my models.
16
+ This was a big overhead to do all of that with all resources, so I decided to create a generator to do all that work for me.
17
+
18
+ == How to install
19
+ To install QuickMagick just type at your command line:
20
+ gem install nested_restful_scaffold
21
+ ... and it's done.
22
+ You don't have to install any libraries or compile code from source.
23
+
24
+ == How to use
25
+ Usage:
26
+ ./script/generate nested_restful_scaffold ModelName [field:type, field:type, resource1,resource2,...:resources]
27
+
28
+ Lets start with an example of library resource and each library has books and each book has pages.
29
+
30
+ === Library Resource
31
+ Use the following command to create library resource
32
+ ./script/generate nested_restful_scaffold library name:string address:text
33
+ It will use rails scaffold generator because there isn't any nested resources included in the previous command.
34
+
35
+ === Book & Page Resources
36
+ Use the following command to create library resource
37
+ ./script/generate nested_restful_scaffold book name:string description:text library:references library:resources
38
+ ./script/generate nested_restful_scaffold page contents:text book:references library,book:resources
39
+
40
+ As it is shown, we used <b>library:resources</b> for books resources and <b>library,book:resources</b> for pages resources.
41
+ They will do the same job of rails scaffold generator in addition to the following:
42
+ N.B. i will explain the result of the pages generation and it will be the same for book resources.
43
+
44
+ * It updated the routes.rb file with libraries, books and pages routing to be as the following:
45
+ map.resources :libraries do |library|
46
+ library.resources :books do |book|
47
+ book.resources :pages
48
+ end
49
+ end
50
+ If you run rake routes, we can see the pages routes as the following:
51
+ library_book_pages GET /libraries/:library_id/books/:book_id/pages {:controller=>"pages", :action=>"index"}
52
+ formatted_library_book_pages GET /libraries/:library_id/books/:book_id/pages.:format {:controller=>"pages", :action=>"index"}
53
+ POST /libraries/:library_id/books/:book_id/pages {:controller=>"pages", :action=>"create"}
54
+ POST /libraries/:library_id/books/:book_id/pages.:format {:controller=>"pages", :action=>"create"}
55
+ new_library_book_page GET /libraries/:library_id/books/:book_id/pages/new {:controller=>"pages", :action=>"new"}
56
+ formatted_new_library_book_page GET /libraries/:library_id/books/:book_id/pages/new.:format {:controller=>"pages", :action=>"new"}
57
+ edit_library_book_page GET /libraries/:library_id/books/:book_id/pages/:id/edit {:controller=>"pages", :action=>"edit"}
58
+ formatted_edit_library_book_page GET /libraries/:library_id/books/:book_id/pages/:id/edit.:format {:controller=>"pages", :action=>"edit"}
59
+ library_book_page GET /libraries/:library_id/books/:book_id/pages/:id {:controller=>"pages", :action=>"show"}
60
+ formatted_library_book_page GET /libraries/:library_id/books/:book_id/pages/:id.:format {:controller=>"pages", :action=>"show"}
61
+ PUT /libraries/:library_id/books/:book_id/pages/:id {:controller=>"pages", :action=>"update"}
62
+ PUT /libraries/:library_id/books/:book_id/pages/:id.:format {:controller=>"pages", :action=>"update"}
63
+ DELETE /libraries/:library_id/books/:book_id/pages/:id {:controller=>"pages", :action=>"destroy"}
64
+ DELETE /libraries/:library_id/books/:book_id/pages/:id.:format {:controller=>"pages", :action=>"destroy"}
65
+
66
+ * Pages controller has new method book to get its parent resource
67
+ protected
68
+ def book
69
+ @book ||= Library.find(params[:library_id]).books.find(params[:book_id])
70
+ end
71
+ * All ActiveRecord calls for page resource will be through its book to be well scoped.
72
+ @pages = book.pages
73
+ * The most bunch of work in in views files
74
+ <td><%= link_to 'Show', library_book_page_path(page.book.library,page.book,page) %></td>
75
+ <td><%= link_to 'Edit', edit_library_book_page_path(page.book.library,page.book,page) %></td>
76
+ <td><%= link_to 'Destroy', library_book_page_path(page.book.library,page.book,page), :confirm => 'Are you sure?', :method => :delete %></td>
77
+ and two links at the end of the html page to new page and to return to books page
78
+ <%= link_to 'New page', new_library_book_page_path %>
79
+ <%= link_to 'Return to books', library_books_path %>
80
+ * In book.rb model file, there will be new line added to define association
81
+ has_many :pages
82
+ and in page.rb model file, also there will be new line added
83
+ belongs_to :book
84
+
85
+ == Conclusion
86
+ NestedRestfulScaffold is very easy to install, very easy to use and allows you to generate all that work for you.
87
+ It will be very suitable for you if you are building a RESTful API or application with nested resources.
88
+ It will reduce the overhead of updating controller, views, models and routes.
89
+
90
+ For more information on nested resources check:
91
+ http://adam.blog.heroku.com/past/2007/12/20/nested_resources_in_rails_2
92
+ http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('nested_restful_scaffold', '0.1.0') do |p|
6
+ p.description = "NestedRestfulScaffold allows you to generate controller, views, model and routes of nested resources."
7
+ p.url = "http://nestedrestfulscaffold.rubyforge.org/"
8
+ p.author = "Mahmoud Khaled"
9
+ p.email = "mahmoud.khaled@badrit.com"
10
+ p.project = "nestedrestscaff"
11
+ end
12
+
13
+ #Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
14
+
@@ -0,0 +1,31 @@
1
+ Description:
2
+ Scaffolds an entire resource, from model and migration to controller and
3
+ views, along with a full test suite. The resource is ready to use for your
4
+ restful, resource-oriented application.
5
+
6
+ Usage:
7
+ Pass the name of the model, either CamelCased or under_scored, as the first
8
+ argument, an optional list of attribute pairs, and an optional list of
9
+ resources tree comma separated.
10
+
11
+ Attribute pairs are column_name:sql_type arguments specifying the
12
+ model's attributes. Timestamps are added by default, so you don't have to
13
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
14
+
15
+ You don't have to think up every attribute up front, but it helps to
16
+ sketch out a few so you can start working with the resource immediately.
17
+
18
+ Resources list is an ordered list of nested parent resources. They are comma
19
+ separated ordered from root to child. 'library,book,page:resources'
20
+
21
+ For example, `nested_restful_scaffold page page_number:integer contents:text
22
+ book:references library,book:resources`
23
+ gives you a model with attributes page_number, contents and book_id, a controller that handles
24
+ the create/show/update/destroy, forms to create and edit your posts, and
25
+ an index that lists them all, as well as a book.resources :pages
26
+ declaration in config/routes.rb.
27
+
28
+ Examples:
29
+ `script/generate nested_restful_scaffold library name:string address:text`
30
+ `script/generate nested_restful_scaffold book name:string description:text library:references library:resources `
31
+ `script/generate nested_restful_scaffold page page_number:integer contents:text book:references library,book:resources`
@@ -0,0 +1,285 @@
1
+ class NestedRestfulScaffoldGenerator < Rails::Generator::NamedBase
2
+ default_options :skip_timestamps => false, :skip_migration => false
3
+
4
+ attr_reader :controller_name,
5
+ :controller_class_path,
6
+ :controller_file_path,
7
+ :controller_class_nesting,
8
+ :controller_class_nesting_depth,
9
+ :controller_class_name,
10
+ :controller_underscore_name,
11
+ :controller_singular_name,
12
+ :controller_plural_name
13
+ alias_method :controller_file_name, :controller_underscore_name
14
+ alias_method :controller_table_name, :controller_plural_name
15
+
16
+ def initialize(runtime_args, runtime_options = {})
17
+ super
18
+
19
+ @controller_name = @name.pluralize
20
+
21
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
22
+ @controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name)
23
+ @controller_singular_name=base_name.singularize
24
+ if @controller_class_nesting.empty?
25
+ @controller_class_name = @controller_class_name_without_nesting
26
+ else
27
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
28
+ end
29
+
30
+ # Remove resources from attributes
31
+ # and push them in new instance varialbe @resources
32
+ # to separate between resources attributes and other attributes
33
+ @resources = []
34
+ attributes.delete_if{|a| a.type.to_s == 'resources' and @resources = a.name.split(',').collect{|e| e.strip} }
35
+ @resources = nil if @resources.empty?
36
+ end
37
+
38
+ def manifest
39
+ record do |m|
40
+ unless command_has_resources
41
+ m.dependency "scaffold", [name] + @args
42
+ else
43
+ # Check for class naming collisions.
44
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
45
+ m.class_collisions(class_path, "#{class_name}")
46
+ m.class_collisions class_path, class_name, "#{class_name}Test"
47
+
48
+ # Controller, helper, views, test and stylesheets directories.
49
+ m.directory(File.join('app/models', class_path))
50
+ m.directory(File.join('app/controllers', controller_class_path))
51
+ m.directory(File.join('app/helpers', controller_class_path))
52
+ m.directory(File.join('app/views', controller_class_path, controller_file_name))
53
+ m.directory(File.join('app/views/layouts', controller_class_path))
54
+ m.directory(File.join('test/functional', controller_class_path))
55
+ m.directory(File.join('test/unit', class_path))
56
+ m.directory(File.join('public/stylesheets', class_path))
57
+
58
+ # Model, test, and fixture directories.
59
+ m.directory File.join('app/models', class_path)
60
+ m.directory File.join('test/unit', class_path)
61
+ m.directory File.join('test/fixtures', class_path)
62
+
63
+
64
+ for action in scaffold_views
65
+ m.template(
66
+ "view_#{action}.html.erb",
67
+ File.join('app/views', controller_class_path, controller_file_name, "#{action}.html.erb")
68
+ )
69
+ end
70
+
71
+ # Layout and stylesheet.
72
+ m.template('layout.html.erb', File.join('app/views/layouts', controller_class_path, "#{controller_file_name}.html.erb"))
73
+ m.template('style.css', 'public/stylesheets/scaffold.css')
74
+
75
+ m.template(
76
+ "controller.rb", File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
77
+ )
78
+
79
+ m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
80
+ m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
81
+
82
+ # add routes
83
+ generate_routes m
84
+
85
+ # genearte model, unit_test, fixtures and migration
86
+ generate_model m
87
+ end
88
+ end
89
+ end
90
+
91
+ def resources
92
+ @resources
93
+ end
94
+
95
+ def command_has_resources
96
+ !resources.nil?
97
+ end
98
+
99
+ # Return parent resource name
100
+ def parent_resource_name
101
+ command_has_resources ? resources.last : ''
102
+ end
103
+
104
+ # Generate find statement to be used in the controller
105
+ def generate_find_statement
106
+ first_resource = resources.first
107
+ statement = "#{first_resource.classify}.find(params[:#{first_resource}_id])"
108
+
109
+ statement = resources[1..-1].inject(statement){|s, resource| s += ".#{resource.pluralize}.find(params[:#{resource}_id])"}
110
+ end
111
+
112
+ # Generate singular resource
113
+ # prefix can be 'edit' to generate edit_resource_path
114
+ # add_params will be used to generate params with the medthod
115
+ # instance_object if true, it will add "@" to be instance variable
116
+ # plural if true, pluralize the last resource. It is useful for index actions
117
+ # reject_last if true, doesn't add last resource to the path. It is used in index view for "Return to parent resource" link
118
+ def nested_resource_path name, params = {}
119
+ params = {:prefix => "", :add_params => true, :instance_object => false,
120
+ :plural => false, :reject_last => false}.merge(params)
121
+ result = ""
122
+
123
+ result += resources[0..-2] * "_"
124
+ result += "_" unless resources[0..-2].empty?
125
+
126
+ # used only in index view for link "Return to"
127
+ result += params[:plural] && params[:reject_last] ? resources.last.pluralize : resources.last
128
+ result += '_'
129
+
130
+ if params[:reject_last]
131
+ result += "path"
132
+ elsif command_has_resources
133
+ result += params[:plural] ? name.pluralize : name
134
+ result += "_path"
135
+ else
136
+ result = name
137
+ end
138
+
139
+ if !params[:prefix].empty? && !command_has_resources
140
+ result += "_path"
141
+ end
142
+
143
+ force_params = params[:prefix]=="edit"
144
+
145
+ # add parameters to the method
146
+ param_name = name
147
+ param_name = "@" + param_name if params[:instance_object]
148
+ result += nested_resource_path_params(param_name, force_params, params[:plural]) if params[:add_params] || force_params
149
+
150
+ # add prefix "edit" or "new"
151
+ result = params[:prefix] + "_" + result unless params[:prefix].empty?
152
+ result
153
+ end
154
+
155
+ # Return method parameters
156
+ def nested_resource_path_params name, force_params, plural
157
+ result = ""
158
+ attr_params = resources.collect{|r| r}
159
+
160
+ if command_has_resources || force_params
161
+ attr_params << name
162
+ i = resources.size
163
+ while i > 0
164
+ attr_params[i-1] = attr_params[i] + "." + attr_params[i-1]
165
+ i -= 1
166
+ end
167
+
168
+ # skip last attribute if plural
169
+ attr_params = attr_params[0..-2] if plural
170
+
171
+ result = "(" + attr_params.join(',') + ")"
172
+ end
173
+
174
+ result
175
+ end
176
+
177
+ # Generate conditions for find statement to be used in view with input select
178
+ def generate_conditions owner, name
179
+ result = ""
180
+ parent = nil
181
+ has_resource = false
182
+ resources.each do |resource|
183
+ if resource == name
184
+ has_resource = true
185
+ break
186
+ end
187
+
188
+ parent = resource if resource != name
189
+ end
190
+
191
+ result = ", :conditions => [\"#{parent}_id = ?\", @#{owner}.#{name}.#{parent}.id]" if has_resource && parent
192
+ result
193
+ end
194
+
195
+ # Add routes to file routes.rb
196
+ def generate_routes m
197
+ # routes
198
+ unless command_has_resources
199
+ # add routes like unnested scaffold
200
+ # eg. map.resources books
201
+ m.route_resources controller_file_name
202
+ else
203
+ resource_list = controller_file_name.map { |r| r.to_sym.inspect }.join(', ')
204
+ parent_resource = parent_resource_name
205
+
206
+ path = destination_path('config/routes.rb')
207
+ content = File.read(path)
208
+
209
+ logger.route "resources #{resource_list}"
210
+
211
+ # map.resources :parents do |parent|
212
+ # parent.resources :parents do |parent|
213
+ sentinel = "\.resources(.*)?:#{parent_resource.pluralize}(.*)do(.*)\\|#{parent_resource}\\|"
214
+
215
+ if content =~ /#{sentinel}/
216
+ gsub_file 'config/routes.rb', sentinel do |match|
217
+ "#{match}\n #{parent_resource}.resources :#{table_name}"
218
+ end
219
+ else
220
+ # without do block
221
+ # map.resources :parents
222
+ # parent.resources :parents
223
+ sentinel = "\.resources(.*):#{parent_resource.pluralize}"
224
+ if content =~ /#{sentinel}/
225
+ gsub_file 'config/routes.rb', sentinel do |match|
226
+ "#{match} do |#{parent_resource}|\n #{parent_resource}.resources :#{table_name}\n end"
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ # Genearte model, unit_test, fixtures, migration and add has_many relationshipt to parents
234
+ def generate_model m
235
+ # Model class, unit test, and fixtures.
236
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
237
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
238
+
239
+ unless options[:skip_fixture]
240
+ m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
241
+ end
242
+
243
+ unless options[:skip_migration]
244
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
245
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
246
+ }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
247
+ end
248
+
249
+ # add has_many to referenced
250
+ attributes.find_all{|a| a.type.to_s == "references"}.each do |parent|
251
+ gsub_file "app/models/#{parent.name}.rb", "class #{parent.name.camelize} < ActiveRecord::Base" do |match|
252
+ "#{match}\n has_many :#{table_name}"
253
+ end
254
+ end
255
+ end
256
+
257
+ protected
258
+ # Override with your own usage banner.
259
+ def banner
260
+ "Usage: #{$0} nested_restful_scaffold ModelName [field:type, field:type, resource1,resource2,...:resources]"
261
+ end
262
+
263
+ def add_options!(opt)
264
+ opt.separator ''
265
+ opt.separator 'Options:'
266
+ opt.on("--skip-timestamps",
267
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
268
+ opt.on("--skip-migration",
269
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
270
+ end
271
+
272
+ def gsub_file(relative_destination, regexp, *args, &block)
273
+ path = destination_path(relative_destination)
274
+ content = File.read(path).gsub(/#{regexp}/, *args, &block)
275
+ File.open(path, 'wb') { |file| file.write(content) }
276
+ end
277
+
278
+ def scaffold_views
279
+ %w[ index show new edit ]
280
+ end
281
+
282
+ def model_name
283
+ class_name.demodulize
284
+ end
285
+ end
@@ -0,0 +1,94 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ # GET /<%= table_name %>
3
+ # GET /<%= table_name %>.xml
4
+ <% resource_name = parent_resource_name %>
5
+ def index
6
+ @<%= table_name %> = <%= resource_name %>.<%= table_name %>
7
+
8
+ respond_to do |format|
9
+ format.html # index.html.erb
10
+ format.xml { render :xml => @<%= table_name %> }
11
+ end
12
+ end
13
+
14
+ # GET /<%= table_name %>/1
15
+ # GET /<%= table_name %>/1.xml
16
+ def show
17
+ @<%= file_name %> = <%= resource_name %>.<%= table_name %>.find(params[:id])
18
+
19
+ respond_to do |format|
20
+ format.html # show.html.erb
21
+ format.xml { render :xml => @<%= file_name %> }
22
+ end
23
+ end
24
+
25
+ # GET /<%= table_name %>/new
26
+ # GET /<%= table_name %>/new.xml
27
+ def new
28
+ @<%= file_name %> = <%= class_name %>.new
29
+ @<%= file_name %>.<%= resource_name %> = <%= resource_name %>
30
+
31
+ respond_to do |format|
32
+ format.html # new.html.erb
33
+ format.xml { render :xml => @<%= file_name %> }
34
+ end
35
+ end
36
+
37
+ # GET /<%= table_name %>/1/edit
38
+ def edit
39
+ @<%= file_name %> = <%= resource_name %>.<%= table_name %>.find(params[:id])
40
+ end
41
+
42
+ # POST /<%= table_name %>
43
+ # POST /<%= table_name %>.xml
44
+ def create
45
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>]) if params[:<%= file_name %>][:<%= resource_name %>_id].nil? || params[:<%= file_name %>][:<%= resource_name %>_id] == <%= resource_name %>.id.to_s
46
+ @<%= file_name %>.<%= resource_name %>_id = <%= resource_name %>.id
47
+
48
+ respond_to do |format|
49
+ if @<%= file_name %>.save
50
+ flash[:notice] = '<%= class_name %> was successfully created.'
51
+ format.html { redirect_to(<%= nested_resource_path singular_name, :instance_object => true %>) }
52
+ format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
53
+ else
54
+ format.html { render :action => "new" }
55
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
56
+ end
57
+ end
58
+ end
59
+
60
+ # PUT /<%= table_name %>/1
61
+ # PUT /<%= table_name %>/1.xml
62
+ def update
63
+ @<%= file_name %> = <%= resource_name %>.<%= table_name %>.find(params[:id])
64
+
65
+ respond_to do |format|
66
+ if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
67
+ flash[:notice] = '<%= class_name %> was successfully updated.'
68
+ format.html { redirect_to(<%= nested_resource_path singular_name, :instance_object => true %>) }
69
+ format.xml { head :ok }
70
+ else
71
+ format.html { render :action => "edit" }
72
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
73
+ end
74
+ end
75
+ end
76
+
77
+ # DELETE /<%= table_name %>/1
78
+ # DELETE /<%= table_name %>/1.xml
79
+ def destroy
80
+ @<%= file_name %> = <%= resource_name %>.<%= table_name %>.find(params[:id])
81
+ url_path = <%= nested_resource_path singular_name, :instance_object => true, :plural => true %>
82
+ @<%= file_name %>.destroy
83
+
84
+ respond_to do |format|
85
+ format.html { redirect_to(url_path) }
86
+ format.xml { head :ok }
87
+ end
88
+ end
89
+
90
+ protected
91
+ def <%= resource_name %>
92
+ @<%= resource_name %> ||= <%= generate_find_statement %>
93
+ end
94
+ end
@@ -0,0 +1,19 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+
3
+ <% unless attributes.empty? -%>
4
+ one:
5
+ <% for attribute in attributes -%>
6
+ <%= attribute.name %>: <%= attribute.default %>
7
+ <% end -%>
8
+
9
+ two:
10
+ <% for attribute in attributes -%>
11
+ <%= attribute.name %>: <%= attribute.default %>
12
+ <% end -%>
13
+ <% else -%>
14
+ # one:
15
+ # column: value
16
+ #
17
+ # two:
18
+ # column: value
19
+ <% end -%>
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+ def test_should_get_index
5
+ get :index
6
+ assert_response :success
7
+ assert_not_nil assigns(:<%= table_name %>)
8
+ end
9
+
10
+ def test_should_get_new
11
+ get :new
12
+ assert_response :success
13
+ end
14
+
15
+ def test_should_create_<%= file_name %>
16
+ assert_difference('<%= class_name %>.count') do
17
+ post :create, :<%= file_name %> => { }
18
+ end
19
+
20
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
21
+ end
22
+
23
+ def test_should_show_<%= file_name %>
24
+ get :show, :id => <%= table_name %>(:one).id
25
+ assert_response :success
26
+ end
27
+
28
+ def test_should_get_edit
29
+ get :edit, :id => <%= table_name %>(:one).id
30
+ assert_response :success
31
+ end
32
+
33
+ def test_should_update_<%= file_name %>
34
+ put :update, :id => <%= table_name %>(:one).id, :<%= file_name %> => { }
35
+ assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
36
+ end
37
+
38
+ def test_should_destroy_<%= file_name %>
39
+ assert_difference('<%= class_name %>.count', -1) do
40
+ delete :destroy, :id => <%= table_name %>(:one).id
41
+ end
42
+
43
+ assert_redirected_to <%= table_name %>_path
44
+ end
45
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7
+ <title><%= controller_class_name %>: <%%= controller.action_name %></title>
8
+ <%%= stylesheet_link_tag 'scaffold' %>
9
+ </head>
10
+ <body>
11
+
12
+ <p style="color: green"><%%= flash[:notice] %></p>
13
+
14
+ <%%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -0,0 +1,16 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% for attribute in attributes -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% unless options[:skip_timestamps] %>
8
+ t.timestamps
9
+ <% end -%>
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= table_name %>
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+ <% for attribute in attributes -%>
3
+ <%= "belongs_to :#{attribute.name}" if attribute.type.to_s == "references" %>
4
+ <% end -%>
5
+ end
@@ -0,0 +1,54 @@
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
+
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ def test_truth
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ <h1>Editing <%= singular_name %></h1>
2
+
3
+ <%%= error_messages_for :<%= singular_name %> %>
4
+
5
+ <%% form_for(@<%= singular_name %><%= ", :url => " + nested_resource_path(singular_name, :instance_object => true) if command_has_resources %>) do |f| %>
6
+ <% for attribute in attributes -%>
7
+ <p>
8
+ <b><%= attribute.column.human_name %></b><br />
9
+ <% if attribute.type.to_s != "references" %>
10
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
11
+ <% end %>
12
+ </p>
13
+ <% end -%>
14
+ <p>
15
+ <%%= f.submit "Update" %>
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to 'Show', <%= nested_resource_path singular_name, :instance_object => true %> %> |
20
+ <%%= link_to 'Back', <%= nested_resource_path singular_name, :instance_object => true, :plural => true %> %>
@@ -0,0 +1,26 @@
1
+ <h1>Listing <%= plural_name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <% for attribute in attributes -%>
6
+ <th><%= attribute.column.human_name %></th>
7
+ <% end -%>
8
+ </tr>
9
+
10
+ <%% for <%= singular_name %> in @<%= plural_name %> %>
11
+ <tr>
12
+ <% for attribute in attributes -%>
13
+ <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
14
+ <% end -%>
15
+ <td><%%= link_to 'Show', <%= nested_resource_path singular_name %> %></td>
16
+ <td><%%= link_to 'Edit', <%= nested_resource_path singular_name, :prefix => "edit" %> %></td>
17
+ <td><%%= link_to 'Destroy', <%= nested_resource_path singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
18
+ </tr>
19
+ <%% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%%= link_to 'New <%= singular_name %>', <%= nested_resource_path singular_name, :prefix => "new", :add_params => false %> %>
25
+ <br />
26
+ <%%= link_to 'Return to <%= parent_resource_name.pluralize %>', <%= nested_resource_path singular_name, :add_params => false, :plural => true, :reject_last => true %> %>
@@ -0,0 +1,19 @@
1
+ <h1>New <%= singular_name %></h1>
2
+
3
+ <%%= error_messages_for :<%= singular_name %> %>
4
+
5
+ <%% form_for(@<%= singular_name %><%= ", :url => " + nested_resource_path(singular_name, :instance_object => true, :plural => true) if command_has_resources %>) do |f| %>
6
+ <% for attribute in attributes -%>
7
+ <p>
8
+ <b><%= attribute.column.human_name %></b><br />
9
+ <% if attribute.type.to_s != "references" %>
10
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
11
+ <% end %>
12
+ </p>
13
+ <% end -%>
14
+ <p>
15
+ <%%= f.submit "Create" %>
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to 'Back', <%= nested_resource_path singular_name, :instance_object => true, :plural => true %> %>
@@ -0,0 +1,9 @@
1
+ <% for attribute in attributes -%>
2
+ <p>
3
+ <b><%= attribute.column.human_name %>:</b>
4
+ <%%=h @<%= singular_name %>.<%= attribute.name %> %>
5
+ </p>
6
+ <% end -%>
7
+
8
+ <%%= link_to 'Edit', <%= nested_resource_path(singular_name, :prefix => "edit", :instance_object => true) %> %> |
9
+ <%%= link_to 'Back', <%= nested_resource_path singular_name, :instance_object => true, :plural => true %> %>
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{nested_restful_scaffold}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Mahmoud Khaled"]
9
+ s.date = %q{2009-09-17}
10
+ s.description = %q{NestedRestfulScaffold allows you to generate controller, views, model and routes of nested resources.}
11
+ s.email = %q{mahmoud.khaled@badrit.com}
12
+ s.extra_rdoc_files = ["README"]
13
+ s.files = ["README", "Rakefile", "generators/nested_restful_scaffold/USAGE", "generators/nested_restful_scaffold/nested_restful_scaffold_generator.rb", "generators/nested_restful_scaffold/templates/controller.rb", "generators/nested_restful_scaffold/templates/fixtures.yml", "generators/nested_restful_scaffold/templates/functional_test.rb", "generators/nested_restful_scaffold/templates/helper.rb", "generators/nested_restful_scaffold/templates/layout.html.erb", "generators/nested_restful_scaffold/templates/migration.rb", "generators/nested_restful_scaffold/templates/model.rb", "generators/nested_restful_scaffold/templates/style.css", "generators/nested_restful_scaffold/templates/unit_test.rb", "generators/nested_restful_scaffold/templates/view_edit.html.erb", "generators/nested_restful_scaffold/templates/view_index.html.erb", "generators/nested_restful_scaffold/templates/view_new.html.erb", "generators/nested_restful_scaffold/templates/view_show.html.erb", "nested_restful_scaffold.gemspec", "Manifest"]
14
+ s.homepage = %q{http://nestedrestfulscaffold.rubyforge.org/}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Nested_restful_scaffold", "--main", "README"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{nestedrestscaff}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{NestedRestfulScaffold allows you to generate controller, views, model and routes of nested resources.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nested_restful_scaffold
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mahmoud Khaled
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-17 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: NestedRestfulScaffold allows you to generate controller, views, model and routes of nested resources.
17
+ email: mahmoud.khaled@badrit.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - README
26
+ - Rakefile
27
+ - generators/nested_restful_scaffold/USAGE
28
+ - generators/nested_restful_scaffold/nested_restful_scaffold_generator.rb
29
+ - generators/nested_restful_scaffold/templates/controller.rb
30
+ - generators/nested_restful_scaffold/templates/fixtures.yml
31
+ - generators/nested_restful_scaffold/templates/functional_test.rb
32
+ - generators/nested_restful_scaffold/templates/helper.rb
33
+ - generators/nested_restful_scaffold/templates/layout.html.erb
34
+ - generators/nested_restful_scaffold/templates/migration.rb
35
+ - generators/nested_restful_scaffold/templates/model.rb
36
+ - generators/nested_restful_scaffold/templates/style.css
37
+ - generators/nested_restful_scaffold/templates/unit_test.rb
38
+ - generators/nested_restful_scaffold/templates/view_edit.html.erb
39
+ - generators/nested_restful_scaffold/templates/view_index.html.erb
40
+ - generators/nested_restful_scaffold/templates/view_new.html.erb
41
+ - generators/nested_restful_scaffold/templates/view_show.html.erb
42
+ - nested_restful_scaffold.gemspec
43
+ - Manifest
44
+ has_rdoc: true
45
+ homepage: http://nestedrestfulscaffold.rubyforge.org/
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --line-numbers
51
+ - --inline-source
52
+ - --title
53
+ - Nested_restful_scaffold
54
+ - --main
55
+ - README
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "1.2"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project: nestedrestscaff
73
+ rubygems_version: 1.3.5
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: NestedRestfulScaffold allows you to generate controller, views, model and routes of nested resources.
77
+ test_files: []
78
+