nested_restful_scaffold 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+