Skip to content
Browse files

Added script/generate resource which works just like scaffold_resourc…

…e, but creates empty placeholders instead of predefined [DHH] Added generated attribute options to script/generate model, like the one found in scaffold_resource and resource [DHH]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5236 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 5728b82 commit c16a4379caaa9e086aeeb58a9194e511c40921d9 @dhh dhh committed Oct 9, 2006
View
6 railties/CHANGELOG
@@ -1,5 +1,11 @@
*SVN*
+* Added generated attribute options to script/generate model, like the one found in scaffold_resource and resource [DHH]. Examples:
+
+ ./script/generate model post title:string created_on:date body:text published:boolean
+
+* Added script/generate resource which works just like scaffold_resource, but creates empty placeholders instead of predefined [DHH]
+
* script/runner can run files, pass on arguments, and be used as a shebang. #6286 [Tuxie, dlpond]
#!/usr/bin/env /path/to/my/app/script/runner
# Example: just start using your models as if you are in script/console
View
8 railties/lib/rails_generator/base.rb
@@ -1,6 +1,7 @@
require File.dirname(__FILE__) + '/options'
require File.dirname(__FILE__) + '/manifest'
require File.dirname(__FILE__) + '/spec'
+require File.dirname(__FILE__) + '/generated_attribute'
# Rails::Generator is a code generation platform tailored for the Rails
# web application framework. Generators are easily invoked within Rails
@@ -165,6 +166,13 @@ def initialize(runtime_args, runtime_options = {})
def banner
"Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]"
end
+
+ def attributes
+ @attributes ||= @args.collect do |attribute|
+ Rails::Generator::GeneratedAttribute.new(*attribute.split(":"))
+ end
+ end
+
private
def assign_names!(name)
View
42 railties/lib/rails_generator/generated_attribute.rb
@@ -0,0 +1,42 @@
+require 'optparse'
+
+module Rails
+ module Generator
+ class GeneratedAttribute
+ attr_accessor :name, :type, :column
+
+ def initialize(name, type)
+ @name, @type = name, type.to_sym
+ @column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type)
+ end
+
+ def field_type
+ @field_type ||= case type
+ when :integer, :float, :decimal then :text_field
+ when :datetime, :timestamp, :time then :datetime_select
+ when :date then :date_select
+ when :string then :text_field
+ when :text then :text_area
+ when :boolean then :check_box
+ else
+ :text_field
+ end
+ end
+
+ def default
+ @default ||= case type
+ when :integer then 1
+ when :float then 1.5
+ when :decimal then "9.99"
+ when :datetime, :timestamp, :time then Time.now.to_s(:db)
+ when :date then Date.today.to_s(:db)
+ when :string then "MyString"
+ when :text then "MyText"
+ when :boolean then false
+ else
+ ""
+ end
+ end
+ end
+ end
+end
View
31 railties/lib/rails_generator/generators/components/model/USAGE
@@ -1,19 +1,26 @@
Description:
The model generator creates stubs for a new model.
- The generator takes a model name as its argument. The model name may be
- given in CamelCase or under_score and should not be suffixed with 'Model'.
+ The generator takes a model name as its argument. The model name may be given in CamelCase or under_score and
+ should not be suffixed with 'Model'.
- The generator creates a model class in app/models, a test suite in
- test/unit, test fixtures in test/fixtures/singular_name.yml, and a migration
- in db/migrate.
+ As additional parameters, the generator will take attribute pairs described by name and type. These attributes will
+ be used to prepopulate the migration to create the table for the model and give you a set of predefined fixture.
+ You don't have to think up all attributes up front, but it's a good idea of adding just the baseline of what's
+ needed to start really working with the resource.
-Example:
- ./script/generate model Account
+ The generator creates a model class in app/models, a test suite in test/unit, test fixtures in
+ test/fixtures/singular_name.yml, and a migration in db/migrate.
- This will create an Account model:
- Model: app/models/account.rb
- Test: test/unit/account_test.rb
- Fixtures: test/fixtures/accounts.yml
- Migration: db/migrate/XXX_add_accounts.rb
+Examples:
+ ./script/generate model account
+ This will create an Account model:
+ Model: app/models/account.rb
+ Test: test/unit/account_test.rb
+ Fixtures: test/fixtures/accounts.yml
+ Migration: db/migrate/XXX_add_accounts.rb
+
+ ./script/generate model post title:string created_on:date body:text published:boolean
+
+ Creates post model with predefined attributes.
View
10 railties/lib/rails_generator/generators/components/model/templates/fixtures.yml
@@ -1,5 +1,11 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-first:
+one:
id: 1
-another:
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
+two:
id: 2
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
View
4 railties/lib/rails_generator/generators/components/model/templates/migration.rb
@@ -1,7 +1,9 @@
class <%= migration_name %> < ActiveRecord::Migration
def self.up
create_table :<%= table_name %> do |t|
- # t.column :name, :string
+<% for attribute in attributes -%>
+ t.column :<%= attribute.name %>, :<%= attribute.type %>
+<% end -%>
end
end
View
86 railties/lib/rails_generator/generators/components/resource/resource_generator.rb
@@ -0,0 +1,86 @@
+class ResourceGenerator < Rails::Generator::NamedBase
+ attr_reader :controller_name,
+ :controller_class_path,
+ :controller_file_path,
+ :controller_class_nesting,
+ :controller_class_nesting_depth,
+ :controller_class_name,
+ :controller_singular_name,
+ :controller_plural_name
+ alias_method :controller_file_name, :controller_singular_name
+ alias_method :controller_table_name, :controller_plural_name
+
+ def initialize(runtime_args, runtime_options = {})
+ super
+
+ @controller_name = @name.pluralize
+
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
+
+ if @controller_class_nesting.empty?
+ @controller_class_name = @controller_class_name_without_nesting
+ else
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
+ end
+ end
+
+ def manifest
+ recorded_session = record do |m|
+ # Check for class naming collisions.
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
+ m.class_collisions(class_path, "#{class_name}")
+
+ # Controller, helper, views, and test directories.
+ m.directory(File.join('app/models', class_path))
+ m.directory(File.join('app/controllers', controller_class_path))
+ m.directory(File.join('app/helpers', controller_class_path))
+ m.directory(File.join('app/views', controller_class_path, controller_file_name))
+ m.directory(File.join('test/functional', controller_class_path))
+ m.directory(File.join('test/unit', class_path))
+
+ m.template('model.rb', File.join('app/models', class_path, "#{file_name}.rb"))
+
+ m.template(
+ 'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
+ )
+
+ m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
+ m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
+ m.template('unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb"))
+ m.template('fixtures.yml', File.join('test/fixtures', "#{table_name}.yml"))
+
+ unless options[:skip_migration]
+ m.migration_template(
+ 'migration.rb', 'db/migrate',
+ :assigns => {
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}",
+ :attributes => attributes
+ },
+ :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
+ )
+ end
+ end
+
+ puts
+ puts ("-" * 70)
+ puts "Don't forget the restful route in config/routes.rb"
+ puts
+ puts " map.resources :#{controller_file_name}"
+ puts
+ puts ("-" * 70)
+ puts
+
+ recorded_session
+ end
+
+ protected
+ # Override with your own usage banner.
+ def banner
+ "Usage: #{$0} resource ModelName [field:type, field:type]"
+ end
+
+ def model_name
+ class_name.demodulize
+ end
+end
View
18 railties/lib/rails_generator/generators/components/resource/templates/USAGE
@@ -0,0 +1,18 @@
+Description:
+ The resource generator creates an empty model and controller for use in a REST-friendly, resource-oriented
+ application. Say you want to a resource called post. Normally, you could just call "script/generate model post" and
+ "script/generate controller posts". This generator basically just collapses these two generators into one step.
+
+ The generator takes the name of the model as its first argument. This model name is then pluralized to get the
+ controller name. So "resource post" will generate a Post model and a PostsController and will be intended
+ for URLs like /posts and /posts/45.
+
+ As additional parameters, the generator will take attribute pairs described by name and type. These attributes will
+ be used to prepopulate the migration to create the table for the model and give you a set of predefined fixture.
+ You don't have to think up all attributes up front, but it's a good idea of adding just the baseline of what's
+ needed to start really working with the resource.
+
+Examples:
+ ./script/generate resource post
+ ./script/generate resource post title:string created_on:date body:text published:boolean
+ ./script/generate resource purchase order_id:integer created_at:datetime amount:decimal
View
2 railties/lib/rails_generator/generators/components/resource/templates/controller.rb
@@ -0,0 +1,2 @@
+class <%= controller_class_name %>Controller < ApplicationController
+end
View
11 railties/lib/rails_generator/generators/components/resource/templates/fixtures.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
+two:
+ id: 2
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
View
20 railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb
@@ -0,0 +1,20 @@
+require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
+require '<%= controller_file_path %>_controller'
+
+# Re-raise errors caught by the controller.
+class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
+
+class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
+ fixtures :<%= table_name %>
+
+ def setup
+ @controller = <%= controller_class_name %>Controller.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
View
2 railties/lib/rails_generator/generators/components/resource/templates/helper.rb
@@ -0,0 +1,2 @@
+module <%= controller_class_name %>Helper
+end
View
13 railties/lib/rails_generator/generators/components/resource/templates/migration.rb
@@ -0,0 +1,13 @@
+class <%= migration_name %> < ActiveRecord::Migration
+ def self.up
+ create_table :<%= table_name %> do |t|
+<% for attribute in attributes -%>
+ t.column :<%= attribute.name %>, :<%= attribute.type %>
+<% end -%>
+ end
+ end
+
+ def self.down
+ drop_table :<%= table_name %>
+ end
+end
View
2 railties/lib/rails_generator/generators/components/resource/templates/model.rb
@@ -0,0 +1,2 @@
+class <%= class_name %> < ActiveRecord::Base
+end
View
10 railties/lib/rails_generator/generators/components/resource/templates/unit_test.rb
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
+
+class <%= class_name %>Test < Test::Unit::TestCase
+ fixtures :<%= table_name %>
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
View
2 railties/lib/rails_generator/generators/components/scaffold_resource/USAGE
@@ -23,7 +23,7 @@ Description:
add "map.resources :posts" (notice the plural form) in the routes file. Then your new resource is accessible from
/posts.
-Example:
+Examples:
./script/generate scaffold_resource post # no attributes, view will be anemic
./script/generate scaffold_resource post title:string created_on:date body:text published:boolean
./script/generate scaffold_resource purchase order_id:integer created_at:datetime amount:decimal
View
45 ...ib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb
@@ -1,41 +1,4 @@
class ScaffoldResourceGenerator < Rails::Generator::NamedBase
- class ScaffoldAttribute
- attr_accessor :name, :type, :column
-
- def initialize(name, type)
- @name, @type = name, type.to_sym
- @column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type)
- end
-
- def field_type
- @field_type ||= case type
- when :integer, :float, :decimal then :text_field
- when :datetime, :timestamp, :time then :datetime_select
- when :date then :date_select
- when :string then :text_field
- when :text then :text_area
- when :boolean then :check_box
- else
- :text_field
- end
- end
-
- def default
- @default ||= case type
- when :integer then 1
- when :float then 1.5
- when :decimal then "9.99"
- when :datetime, :timestamp, :time then Time.now.to_s(:db)
- when :date then Date.today.to_s(:db)
- when :string then "MyString"
- when :text then "MyText"
- when :boolean then false
- else
- ""
- end
- end
- end
-
attr_reader :controller_name,
:controller_class_path,
:controller_file_path,
@@ -121,7 +84,7 @@ def manifest
protected
# Override with your own usage banner.
def banner
- "Usage: #{$0} scaffold_resource ModelName"
+ "Usage: #{$0} scaffold_resource ModelName [field:type, field:type]"
end
def scaffold_views
@@ -131,10 +94,4 @@ def scaffold_views
def model_name
class_name.demodulize
end
-
- def attributes
- @attributes ||= args.collect do |attribute|
- ScaffoldAttribute.new(*attribute.split(":"))
- end
- end
end

0 comments on commit c16a437

Please sign in to comment.
Something went wrong with that request. Please try again.