1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Added script/generate resource which works just like scaffold_resource, 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
This commit is contained in:
David Heinemeier Hansson 2006-10-09 00:08:13 +00:00
parent 5728b82c01
commit c16a4379ca
17 changed files with 252 additions and 60 deletions

View file

@ -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 file

@ -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 @@ module Rails
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 file

@ -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 file

@ -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 file

@ -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 file

@ -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 file

@ -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 file

@ -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 file

@ -0,0 +1,2 @@
class <%= controller_class_name %>Controller < ApplicationController
end

View file

@ -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 file

@ -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 file

@ -0,0 +1,2 @@
module <%= controller_class_name %>Helper
end

View file

@ -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 file

@ -0,0 +1,2 @@
class <%= class_name %> < ActiveRecord::Base
end

View file

@ -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 file

@ -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 file

@ -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 @@ class ScaffoldResourceGenerator < Rails::Generator::NamedBase
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 @@ class ScaffoldResourceGenerator < Rails::Generator::NamedBase
def model_name
class_name.demodulize
end
def attributes
@attributes ||= args.collect do |attribute|
ScaffoldAttribute.new(*attribute.split(":"))
end
end
end