diff options
Diffstat (limited to 'railties/lib/rails_generator/generators')
30 files changed, 820 insertions, 0 deletions
diff --git a/railties/lib/rails_generator/generators/applications/app/USAGE b/railties/lib/rails_generator/generators/applications/app/USAGE new file mode 100644 index 0000000000..3bb55113fa --- /dev/null +++ b/railties/lib/rails_generator/generators/applications/app/USAGE @@ -0,0 +1,16 @@ +Description: + The 'rails' command creates a new Rails application with a default + directory structure and configuration at the path you specify. + +Example: + rails ~/Code/Ruby/weblog + + This generates a skeletal Rails installation in ~/Code/Ruby/weblog. + See the README in the newly created application to get going. + +WARNING: + Only specify --without-gems if you did not use gems to install Rails. + Your application will expect to find activerecord, actionpack, and + actionmailer directories in the vendor directory. A popular way to track + the bleeding edge of Rails development is to checkout from source control + directly to the vendor directory. See http://dev.rubyonrails.com diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb new file mode 100644 index 0000000000..0beb11b237 --- /dev/null +++ b/railties/lib/rails_generator/generators/applications/app/app_generator.rb @@ -0,0 +1,118 @@ +class AppGenerator < Rails::Generator::Base + DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], + Config::CONFIG['ruby_install_name']) + + default_options :gem => true, :shebang => DEFAULT_SHEBANG + mandatory_options :source => "#{File.dirname(__FILE__)}/../.." + + def initialize(runtime_args, runtime_options = {}) + super + usage if args.empty? + @destination_root = args.shift + puts "eek! #{destination_root.inspect}" + end + + def manifest + script_options = { :chmod => 0755, :shebang => options[:shebang] } + + record do |m| + # Root directory and all subdirectories. + m.directory '' + BASEDIRS.each { |path| m.directory path } + + # Root + m.file "fresh_rakefile", "Rakefile" + m.file "README", "README" + m.file "CHANGELOG", "CHANGELOG" + + # Application + m.template "helpers/application.rb", "app/controllers/application.rb" + m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb" + m.template "helpers/test_helper.rb", "test/test_helper.rb" + + # database.yml and .htaccess + m.template "configs/database.yml", "config/database.yml" + m.template "configs/apache.conf", "public/.htaccess" + + # Environments + if options[:gem] + m.file "environments/shared_for_gem.rb", "config/environment.rb" + else + m.file "environments/shared.rb", "config/environment.rb" + end + m.file "environments/production.rb", "config/environments/production.rb" + m.file "environments/development.rb", "config/environments/development.rb" + m.file "environments/test.rb", "config/environments/test.rb" + + # Scripts + %w(console destroy generate server).each do |file| + m.file "bin/#{file}", "script/#{file}", script_options + end + if options[:gem] + m.file "bin/breakpointer_for_gem", "script/breakpointer", script_options + else + m.file "bin/breakpointer", "script/breakpointer", script_options + end + + # Dispatches + m.file "dispatches/dispatch.rb", "public/dispatch.rb", script_options + m.file "dispatches/dispatch.rb", "public/dispatch.cgi", script_options + m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", script_options + + # HTML files + %w(404 500 index).each do |file| + m.template "html/#{file}.html", "public/#{file}.html" + end + + # Docs + m.template "doc/index.html", "public/_doc/index.html" + m.file "doc/README_FOR_APP", "doc/README_FOR_APP" + + # Logs + %w(apache production development test).each { |file| + m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666 + } + end + end + + protected + def banner + "Usage: #{$0} /path/to/your/app [options]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--ruby [#{DEFAULT_SHEBANG}]", + "Path to the Ruby binary of your choice.") { |options[:shebang]| } + opt.on("--without-gems", + "Don't use the Rails gems for your app.", + "WARNING: see note below.") { |options[:gem]| } + end + + + # Installation skeleton. Intermediate directories are automatically + # created so don't sweat their absence here. + BASEDIRS = %w( + app/controllers + app/helpers + app/models + app/views/layouts + config/environments + db + doc + lib + log + public/_doc + public/images + public/javascripts + public/stylesheets + script + test/fixtures + test/functional + test/mocks/development + test/mocks/testing + test/unit + vendor + ) +end diff --git a/railties/lib/rails_generator/generators/components/controller/USAGE b/railties/lib/rails_generator/generators/components/controller/USAGE new file mode 100644 index 0000000000..ec64209135 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/USAGE @@ -0,0 +1,30 @@ +Description: + The controller generator creates stubs for a new controller and its views. + + The generator takes a controller name and a list of views as arguments. + The controller name may be given in CamelCase or under_score and should + not be suffixed with 'Controller'. To create a controller within a + module, specify the controller name as 'module/controller'. + + The generator creates a controller class in app/controllers with view + templates in app/views/controller_name, a helper class in app/helpers, + and a functional test suite in test/functional. + +Example: + ./script/generate controller CreditCard open debit credit close + + Credit card controller with URLs like /credit_card/debit. + Controller: app/controllers/credit_card_controller.rb + Views: app/views/credit_card/debit.rhtml [...] + Helper: app/helpers/credit_card_helper.rb + Test: test/functional/credit_card_controller_test.rb + +Modules Example: + ./script/generate controller 'admin/credit_card' suspend late_fee + + Credit card admin controller with URLs /admin/credit_card/suspend. + Controller: app/controllers/admin/credit_card_controller.rb + Views: app/views/admin/credit_card/debit.rhtml [...] + Helper: app/helpers/admin/credit_card_helper.rb + Test: test/functional/admin/credit_card_controller_test.rb + diff --git a/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb new file mode 100644 index 0000000000..1f7e69d124 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/controller_generator.rb @@ -0,0 +1,34 @@ +class ControllerGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper" + + # Views directory even if there are no actions. + m.directory File.join('app/views', class_path, file_name) + + # Controller class, functional test, and helper class. + m.template 'controller.rb', + File.join('app/controllers', + class_path, + "#{file_name}_controller.rb") + + m.template 'functional_test.rb', + File.join('test/functional', + class_path, + "#{file_name}_controller_test.rb") + + m.template 'helper.rb', + File.join('app/helpers', + class_path, + "#{file_name}_helper.rb") + + # View template for each action. + actions.each do |action| + m.template 'view.rhtml', + File.join('app/views', class_path, file_name, "#{action}.rhtml"), + :assigns => { :action => action } + end + end + end +end diff --git a/railties/lib/rails_generator/generators/components/controller/templates/controller.rb b/railties/lib/rails_generator/generators/components/controller/templates/controller.rb new file mode 100644 index 0000000000..da71b5f057 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/templates/controller.rb @@ -0,0 +1,10 @@ +class <%= class_name %>Controller < ApplicationController +<% if options[:scaffold] -%> + scaffold :<%= singular_name %> +<% end -%> +<% for action in actions -%> + + def <%= action %> + end +<% end -%> +end diff --git a/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb new file mode 100644 index 0000000000..c975cb3ce3 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb @@ -0,0 +1,17 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= file_name %>_controller' + +# Re-raise errors caught by the controller. +class <%= class_name %>Controller; def rescue_action(e) raise e end; end + +class <%= class_name %>ControllerTest < Test::Unit::TestCase + def setup + @controller = <%= class_name %>Controller.new + @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/railties/lib/rails_generator/generators/components/controller/templates/helper.rb b/railties/lib/rails_generator/generators/components/controller/templates/helper.rb new file mode 100644 index 0000000000..3fe2ecdc74 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/templates/helper.rb @@ -0,0 +1,2 @@ +module <%= class_name %>Helper +end diff --git a/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml b/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml new file mode 100644 index 0000000000..7e7a7d53ce --- /dev/null +++ b/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml @@ -0,0 +1,2 @@ +<h1><%= class_name %>#<%= action %></h1> +<p>Find me in app/views/<%= file_name %>/<%= action %>.rhtml</p> diff --git a/railties/lib/rails_generator/generators/components/mailer/USAGE b/railties/lib/rails_generator/generators/components/mailer/USAGE new file mode 100644 index 0000000000..50d3de19de --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/USAGE @@ -0,0 +1,19 @@ +Description: + The mailer generator creates stubs for a new mailer and its views. + + The generator takes a mailer name and a list of views as arguments. + The mailer name may be given in CamelCase or under_score and should + not be suffixed with 'Mailer'. + + The generator creates a mailer class in app/models with view templates + in app/views/mailer_name, and a test suite with fixtures in test/unit. + +Example: + ./script/generate mailer Notifications signup forgot_password invoice + + This will create a NotificationsMailer: + Mailer: app/models/notifications.rb + Views: app/views/notifications/signup.rhtml [...] + Test: test/unit/credit_card_controller_test.rb + Fixtures: test/fixtures/notifications/signup [...] + diff --git a/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb b/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb new file mode 100644 index 0000000000..81d4599f7f --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb @@ -0,0 +1,26 @@ +class MailerGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_name, "#{class_name}Test" + + # Mailer class and unit test. + m.template "mailer.rb", "app/models/#{file_name}.rb" + m.template "unit_test.rb", "test/unit/#{file_name}_test.rb" + + # Views and fixtures directories. + m.directory "app/views/#{file_name}" + m.directory "test/fixtures/#{table_name}" + + # View template and fixture for each action. + actions.each do |action| + m.template "view.rhtml", + "app/views/#{file_name}/#{action}.rhtml", + :assigns => { :action => action } + m.template "fixture.rhtml", + "test/fixtures/#{table_name}/#{action}", + :assigns => { :action => action } + end + end + end +end diff --git a/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml b/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml new file mode 100644 index 0000000000..b481906829 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml @@ -0,0 +1,3 @@ +<%= class_name %>#<%= action %> + +Find me in app/views/<%= file_name %>/<%= action %>.rhtml diff --git a/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb b/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb new file mode 100644 index 0000000000..81c19fa76d --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb @@ -0,0 +1,13 @@ +class <%= class_name %> < ActionMailer::Base +<% for action in actions -%> + + def <%= action %>(sent_on = Time.now) + @subject = '<%= class_name %>#<%= action %>' + @body = {} + @recipients = '' + @from = '' + @sent_on = sent_on + @headers = {} + end +<% end -%> +end diff --git a/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb new file mode 100644 index 0000000000..70fd3afe37 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb @@ -0,0 +1,29 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= file_name %>' + +class <%= class_name %>Test < Test::Unit::TestCase + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' + + def setup + ActionMailer::Base.delivery_method = :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries = [] + + @expected = TMail::Mail.new + end + +<% for action in actions -%> + def test_<%= action %> + @expected.subject = '<%= class_name %>#<%= action %>' + @expected.body = read_fixture('<%= action %>') + @expected.date = Time.now + + assert_equal @expected.encoded, <%= class_name %>.create_<%= action %>(@expected.date).encoded + end + +<% end -%> + private + def read_fixture(action) + IO.readlines("#{FIXTURES_PATH}/<%= file_name %>/#{action}") + end +end diff --git a/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml b/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml new file mode 100644 index 0000000000..b481906829 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml @@ -0,0 +1,3 @@ +<%= class_name %>#<%= action %> + +Find me in app/views/<%= file_name %>/<%= action %>.rhtml diff --git a/railties/lib/rails_generator/generators/components/model/USAGE b/railties/lib/rails_generator/generators/components/model/USAGE new file mode 100644 index 0000000000..f0669104fe --- /dev/null +++ b/railties/lib/rails_generator/generators/components/model/USAGE @@ -0,0 +1,17 @@ +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 creates a model class in app/models, a test suite in + test/unit, and test fixtures in test/fixtures/model_name.yml. + +Example: + ./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 + diff --git a/railties/lib/rails_generator/generators/components/model/model_generator.rb b/railties/lib/rails_generator/generators/components/model/model_generator.rb new file mode 100644 index 0000000000..32577d08a3 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/model/model_generator.rb @@ -0,0 +1,13 @@ +class ModelGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_name, "#{class_name}Test" + + # Model class, unit test, and fixtures. + m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb") + m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml") + end + end +end diff --git a/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml new file mode 100644 index 0000000000..fc3185dc46 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml @@ -0,0 +1,10 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +# Set the $base_id variable in the setup method of your tests. +# It's used to ensure that ids don't clash in some databases. +<%% $base_id ||= 100000 %> + +first_<%= singular_name %>: + id: <%%= $base_id %> + +another_<%= singular_name %>: + id: <%%= $base_id + 1 %> diff --git a/railties/lib/rails_generator/generators/components/model/templates/model.rb b/railties/lib/rails_generator/generators/components/model/templates/model.rb new file mode 100644 index 0000000000..8d4c89e912 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/model/templates/model.rb @@ -0,0 +1,2 @@ +class <%= class_name %> < ActiveRecord::Base +end diff --git a/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb new file mode 100644 index 0000000000..db0fbf5d33 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class <%= class_name %>Test < Test::Unit::TestCase + fixtures :<%= table_name %> + + def setup + $base_id = 1000001 + end + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/railties/lib/rails_generator/generators/components/scaffold/USAGE b/railties/lib/rails_generator/generators/components/scaffold/USAGE new file mode 100644 index 0000000000..d1f29ad63c --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/USAGE @@ -0,0 +1,32 @@ +Description: + The scaffold generator creates a controller to interact with a model. + If the model does not exist, it creates the model as well. The generated + code is equivalent to the "scaffold :model" declaration, making it easy + to migrate when you wish to customize your controller and views. + + The generator takes a model name, an optional controller name, and a + list of views as arguments. Scaffolded actions and views are created + automatically. Any views left over generate empty stubs. + + The scaffolded actions and views are: + index, list, show, new, create, edit, update, destroy + + If a controller name is not given, the plural form of the model name + will be used. The model and controller names may be given in CamelCase + or under_score and should not be suffixed with 'Model' or 'Controller'. + Both model and controller names may be prefixed with a module like a + file path; see the Modules Example for usage. + +Example: + ./script/generate scaffold Account Bank debit credit + + This will generate an Account model and BankController with a full test + suite and a basic user interface. Now create the accounts table in your + database and browse to http://localhost/bank/ -- voila, you're on Rails! + +Modules Example: + ./script/generate controller 'admin/credit_card' suspend late_fee + + This will generate a CreditCard model and CreditCardController controller + in the admin module. + diff --git a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb new file mode 100644 index 0000000000..4445995b46 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb @@ -0,0 +1,161 @@ +class ScaffoldingSandbox + include ActionView::Helpers::ActiveRecordHelper + + attr_accessor :form_action, :singular_name, :suffix, :model_instance + + def sandbox_binding + binding + end +end + +class ActionView::Helpers::InstanceTag + def to_input_field_tag(field_type, options={}) + field_meth = "#{field_type}_field" + "<%= #{field_meth} '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+options.inspect} %>" + end + + def to_text_area_tag(options = {}) + "<%= text_area '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" + end + + def to_date_select_tag(options = {}) + "<%= date_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" + end + + def to_datetime_select_tag(options = {}) + "<%= datetime_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" + end +end + +class ScaffoldGenerator < Rails::Generator::NamedBase + attr_reader :controller_name, + :controller_class_path, + :controller_class_nesting, + :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 = args.shift || @name.pluralize + base_name, @controller_class_path, @controller_class_nesting = extract_modules(@controller_name) + @controller_class_name, @controller_singular_name, @controller_plural_name = inflect_names(base_name) + end + + def manifest + record do |m| + # Depend on model generator but skip if the model exists. + m.dependency 'model', [@name], :collision => :skip + + # Check for class naming collisions. + m.class_collisions "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper" + + # Views directory. + m.directory File.join('app/views', controller_class_path, controller_file_name) + + # Controller class, functional test, helper, and views. + 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 'controller:helper.rb', + File.join('app/helpers', + controller_class_path, + "#{controller_file_name}_helper.rb") + + # Layout and stylesheet. + m.template 'layout.rhtml', "app/views/layouts/#{controller_file_name}.rhtml" + m.template 'style.css', 'public/stylesheets/scaffold.css' + + # Scaffolded views. + scaffold_views.each do |action| + m.template "view_#{action}.rhtml", + File.join('app/views', + controller_class_path, controller_file_name, + "#{action}.rhtml"), + :assigns => { :action => action } + end + + # Scaffolded forms. + scaffold_forms.each do |action| + m.complex_template "view_#{action}.rhtml", + File.join('app/views', + controller_class_path, + controller_file_name, + "#{action}.rhtml"), + :assigns => { :action => action }, + :insert => 'form.rhtml', + :sandbox => lambda { create_sandbox(action) }, + :begin_mark => 'form', + :end_mark => 'eoform', + :mark_id => singular_name + end + + # Unscaffolded views. + unscaffolded_actions.each do |action| + m.template "controller:view.rhtml", + File.join('app/views', + controller_class_path, controller_file_name, + "#{action}.rhtml"), + :assigns => { :action => action } + end + end + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} scaffold ModelName [ControllerName] [action, ...]" + end + + def scaffold_views + %w(list show) + end + + def scaffold_forms + %w(new edit) + end + + def scaffold_actions + scaffold_views + %w(index create update destroy) + end + + def unscaffolded_actions + args - scaffold_actions + end + + def suffix + "_#{singular_name}" if options[:suffix] + end + + def create_sandbox(action) + sandbox = ScaffoldingSandbox.new + action = if action == 'edit' then 'update' else 'create' end + sandbox.form_action = action + sandbox.singular_name = singular_name + begin + sandbox.model_instance = model_instance + sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance) + rescue ActiveRecord::StatementInvalid => e + logger.error "Before updating scaffolding from new DB schema, try creating a table for your model (#{class_name})" + raise SystemExit + end + sandbox.suffix = suffix + sandbox + end + + def model_instance + unless Object.const_defined?(class_name) + Object.const_set(class_name, Class.new(ActiveRecord::Base)) + end + Object.const_get(class_name).new + end +end diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb new file mode 100644 index 0000000000..c409284cb1 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb @@ -0,0 +1,55 @@ +class <%= controller_class_name %>Controller < ApplicationController +<% unless suffix -%> + + def index + list + render_action 'list' + end +<% end -%> + +<% for action in unscaffolded_actions -%> + def <%= action %><%= suffix %> + end + +<% end -%> + def list<%= suffix %> + @<%= plural_name %> = <%= class_name %>.find_all + end + + def show<%= suffix %> + @<%= singular_name %> = <%= class_name %>.find(@params['id']) + end + + def new<%= suffix %> + @<%= singular_name %> = <%= class_name %>.new + end + + def create<%= suffix %> + @<%= singular_name %> = <%= class_name %>.new(@params['<%= singular_name %>']) + if @<%= singular_name %>.save + flash['notice'] = '<%= class_name %> was successfully created.' + redirect_to :action => 'list<%= suffix %>' + else + render_action 'new<%= suffix %>' + end + end + + def edit<%= suffix %> + @<%= singular_name %> = <%= class_name %>.find(@params['id']) + end + + def update + @<%= singular_name %> = <%= class_name %>.find(@params['<%= singular_name %>']['id']) + if @<%= singular_name %>.update_attributes(@params['<%= singular_name %>']) + flash['notice'] = '<%= class_name %> was successfully updated.' + redirect_to :action => 'show<%= suffix %>', :id => @<%= singular_name %>.id + else + render_action 'edit<%= suffix %>' + end + end + + def destroy<%= suffix %> + <%= class_name %>.find(@params['id']).destroy + redirect_to :action => 'list<%= suffix %>' + end +end diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml new file mode 100644 index 0000000000..d314c5f6b5 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml @@ -0,0 +1,5 @@ +<%%= start_form_tag :action => '<%= @form_action %><%= @suffix %>' %> +<%%= hidden_field '<%= @singular_name %>', 'id' %> +<%= all_input_tags(@model_instance, @singular_name, {}) %> +<input type="submit" value="<%= @form_action.to_s.capitalize %>" /> +<%%= end_form_tag %> diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb new file mode 100644 index 0000000000..ea9c8e4e94 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb @@ -0,0 +1,80 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= controller_file_name %>_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 + $base_id = 1000001 + @controller = <%= controller_class_name %>Controller.new + @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new + end + +<% for action in unscaffolded_actions -%> + def test_<%= action %> + process :<%= action %> + assert_rendered_file '<%= action %>' + end + +<% end -%> +<% unless suffix -%> + def test_index + process :index + assert_rendered_file 'list' + end + +<% end -%> + def test_list<%= suffix %> + process :list<%= suffix %> + assert_rendered_file 'list<%= suffix %>' + assert_template_has '<%= plural_name %>' + end + + def test_show<%= suffix %> + process :show<%= suffix %>, 'id' => $base_id + assert_rendered_file 'show' + assert_template_has '<%= singular_name %>' + assert_valid_record '<%= singular_name %>' + end + + def test_new<%= suffix %> + process :new<%= suffix %> + assert_rendered_file 'new<%= suffix %>' + assert_template_has '<%= singular_name %>' + end + + def test_create + num_<%= plural_name %> = <%= class_name %>.find_all.size + + process :create<%= suffix %>, '<%= singular_name %>' => { } + assert_redirected_to :action => 'list<%= suffix %>' + + assert_equal num_<%= plural_name %> + 1, <%= class_name %>.find_all.size + end + + def test_edit<%= suffix %> + process :edit<%= suffix %>, 'id' => $base_id + assert_rendered_file 'edit<%= suffix %>' + assert_template_has '<%= singular_name %>' + assert_valid_record '<%= singular_name %>' + end + + def test_update<%= suffix %> + process :update<%= suffix %>, '<%= singular_name %>' => { 'id' => $base_id } + assert_redirected_to :action => 'show<%= suffix %>', :id => $base_id + end + + def test_destroy<%= suffix %> + assert_not_nil <%= class_name %>.find($base_id) + + process :destroy, 'id' => $base_id + assert_redirected_to :action => 'list<%= suffix %>' + + assert_raise(ActiveRecord::RecordNotFound) { + <%= singular_name %> = <%= class_name %>.find($base_id) + } + end +end diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml new file mode 100644 index 0000000000..c4815bd0a3 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml @@ -0,0 +1,11 @@ +<html> +<head> + <title><%= controller_class_name %>: <%%= controller.action_name %></title> + <link href="/stylesheets/scaffold.css" rel="stylesheet" type="text/css" /> +</head> +<body> + +<%%= @content_for_layout %> + +</body> +</html> diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/style.css b/railties/lib/rails_generator/generators/components/scaffold/templates/style.css new file mode 100644 index 0000000000..95a3c4668c --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/style.css @@ -0,0 +1,53 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { color: #000; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +.fieldWithErrors { + padding: 2px; + background-color: red; + display: table; +} + +#ErrorExplanation { + width: 400px; + border: 2px solid #red; + padding: 7px; + padding-bottom: 12px; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#ErrorExplanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + background-color: #c00; + color: #fff; +} + +#ErrorExplanation p { + color: #333; + margin-bottom: 0; + padding: 5px; +} + +#ErrorExplanation ul li { + font-size: 12px; + list-style: square; +} diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml new file mode 100644 index 0000000000..4ad70f537a --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml @@ -0,0 +1,7 @@ +<h1>Editing <%= singular_name %></h1> + +<%%= error_messages_for '<%= singular_name %>' %> +<%= template_for_inclusion %> + +<%%= link_to 'Show', :action => 'show<%= suffix %>', :id => @<%= singular_name %>.id %> | +<%%= link_to 'Back', :action => 'list<%= suffix %>' %> diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml new file mode 100644 index 0000000000..068fd67472 --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml @@ -0,0 +1,24 @@ +<h1>Listing <%= plural_name %></h1> + +<table> + <tr> +<%% for column in <%= class_name %>.content_columns %> + <th><%%= column.human_name %></th> +<%% end %> + </tr> + +<%% for <%= singular_name %> in @<%= plural_name %> %> + <tr> + <%% for column in <%= class_name %>.content_columns %> + <td><%%=h <%= singular_name %>[column.name] %></td> + <%% end %> + <td><%%= link_to 'Show', :action => 'show<%= suffix %>', :id => <%= singular_name %>.id %></td> + <td><%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => <%= singular_name %>.id %></td> + <td><%%= link_to 'Destroy', :action => 'destroy<%= suffix %>', :id => <%= singular_name %>.id %></td> + </tr> +<%% end %> +</table> + +<br /> + +<%%= link_to 'New <%= singular_name %>', :action => 'new<%= suffix %>' %> diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml new file mode 100644 index 0000000000..fcf5a3c54b --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml @@ -0,0 +1,6 @@ +<h1>New <%= @singular_name %></h1> + +<%%= error_messages_for '<%= singular_name %>' %> +<%= template_for_inclusion %> + +<%%= link_to 'Back', :action => 'list<%= suffix %>' %> diff --git a/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml b/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml new file mode 100644 index 0000000000..ba8f3616dd --- /dev/null +++ b/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml @@ -0,0 +1,8 @@ +<%% for column in <%= class_name %>.content_columns %> +<p> + <b><%%= column.human_name %>:</b> <%%= @<%= singular_name %>.send(column.name) %> +</p> +<%% end %> + +<%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => @<%= singular_name %>.id %> | +<%%= link_to 'Back', :action => 'list<%= suffix %>' %> |