mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Simplifying resource generator.
This commit is contained in:
parent
ff4c600448
commit
95ef9bd67f
5 changed files with 52 additions and 32 deletions
|
@ -91,13 +91,29 @@ module Rails
|
||||||
#
|
#
|
||||||
# ruby script/generate controller Account --no-test-framework
|
# ruby script/generate controller Account --no-test-framework
|
||||||
#
|
#
|
||||||
def self.hook_for(*names)
|
# ==== Custom invocations
|
||||||
|
#
|
||||||
|
# You can also supply a block to hook for to customize how the hook is
|
||||||
|
# going to be invoked. The block receives two parameters, an instance
|
||||||
|
# of the current class and the klass to be invoked.
|
||||||
|
#
|
||||||
|
# For example, in the resource generator, the controller should be invoked
|
||||||
|
# with a pluralized class name. By default, it is invoked with the same
|
||||||
|
# name as the resource generator, which is singular. To change this, we
|
||||||
|
# can give a block to customize how the controller can be invoked.
|
||||||
|
#
|
||||||
|
# hook_for :resource_controller do |instance, controller|
|
||||||
|
# instance.invoke controller, [ instance.name.pluralize ]
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
def self.hook_for(*names, &block)
|
||||||
default_class_options(*names)
|
default_class_options(*names)
|
||||||
options = names.extract_options!
|
options = names.extract_options!
|
||||||
verbose = options.fetch(:verbose, :blue)
|
verbose = options.fetch(:verbose, :blue)
|
||||||
|
|
||||||
names.each do |name|
|
names.each do |name|
|
||||||
invocations << [ name, base_name, generator_name ]
|
invocations << [ name, base_name, generator_name ]
|
||||||
|
invocation_blocks[name] = block if block_given?
|
||||||
|
|
||||||
class_eval <<-METHOD, __FILE__, __LINE__
|
class_eval <<-METHOD, __FILE__, __LINE__
|
||||||
def invoke_for_#{name}
|
def invoke_for_#{name}
|
||||||
|
@ -108,7 +124,7 @@ module Rails
|
||||||
|
|
||||||
if klass
|
if klass
|
||||||
say_status :invoke, options[#{name.inspect}], #{verbose.inspect}
|
say_status :invoke, options[#{name.inspect}], #{verbose.inspect}
|
||||||
invoke klass
|
invoke_class_with_block #{name.inspect}, klass
|
||||||
else
|
else
|
||||||
say "Could not find and invoke '\#{options[#{name.inspect}]}'."
|
say "Could not find and invoke '\#{options[#{name.inspect}]}'."
|
||||||
end
|
end
|
||||||
|
@ -140,13 +156,19 @@ module Rails
|
||||||
#
|
#
|
||||||
# "rails:generators:webrat", "webrat:generators:controller", "webrat"
|
# "rails:generators:webrat", "webrat:generators:controller", "webrat"
|
||||||
#
|
#
|
||||||
def self.invoke_if(*names)
|
# ==== Custom invocations
|
||||||
|
#
|
||||||
|
# This method accepts custom invocations as in hook_for. Check hook_for
|
||||||
|
# for usage and examples.
|
||||||
|
#
|
||||||
|
def self.invoke_if(*names, &block)
|
||||||
conditional_class_options(*names)
|
conditional_class_options(*names)
|
||||||
options = names.extract_options!
|
options = names.extract_options!
|
||||||
verbose = options.fetch(:verbose, :blue)
|
verbose = options.fetch(:verbose, :blue)
|
||||||
|
|
||||||
names.each do |name|
|
names.each do |name|
|
||||||
invocations << [ name, base_name, generator_name ]
|
invocations << [ name, base_name, generator_name ]
|
||||||
|
invocation_blocks[name] = block if block_given?
|
||||||
|
|
||||||
class_eval <<-METHOD, __FILE__, __LINE__
|
class_eval <<-METHOD, __FILE__, __LINE__
|
||||||
def invoke_if_#{name}
|
def invoke_if_#{name}
|
||||||
|
@ -157,7 +179,7 @@ module Rails
|
||||||
|
|
||||||
if klass
|
if klass
|
||||||
say_status :invoke, #{name.inspect}, #{verbose.inspect}
|
say_status :invoke, #{name.inspect}, #{verbose.inspect}
|
||||||
invoke klass
|
invoke_class_with_block #{name.inspect}, klass
|
||||||
else
|
else
|
||||||
say "Could not find and invoke '#{name}'."
|
say "Could not find and invoke '#{name}'."
|
||||||
end
|
end
|
||||||
|
@ -168,6 +190,18 @@ module Rails
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
# This is the common method that both hook_for and invoke_if use to
|
||||||
|
# invoke a class. It searches for a block in the invocation blocks
|
||||||
|
# in case the user wants to customize how the class is invoked.
|
||||||
|
#
|
||||||
|
def invoke_class_with_block(name, klass) #:nodoc:
|
||||||
|
if block = self.class.invocation_blocks[name]
|
||||||
|
block.call(self, klass)
|
||||||
|
else
|
||||||
|
invoke klass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Check whether the given class names are already taken by user
|
# Check whether the given class names are already taken by user
|
||||||
# application or Ruby on Rails.
|
# application or Ruby on Rails.
|
||||||
#
|
#
|
||||||
|
@ -229,6 +263,12 @@ module Rails
|
||||||
@invocations ||= from_superclass(:invocations, [])
|
@invocations ||= from_superclass(:invocations, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Stores invocation blocks used on hook_for and invoke_if.
|
||||||
|
#
|
||||||
|
def self.invocation_blocks #:nodoc:
|
||||||
|
@invocation_blocks ||= from_superclass(:invocation_blocks, {})
|
||||||
|
end
|
||||||
|
|
||||||
# Creates a conditional class option with type boolean, default value
|
# Creates a conditional class option with type boolean, default value
|
||||||
# lookup and default description.
|
# lookup and default description.
|
||||||
#
|
#
|
||||||
|
|
|
@ -3,7 +3,9 @@ require 'generators/rails/model/model_generator'
|
||||||
module Rails
|
module Rails
|
||||||
module Generators
|
module Generators
|
||||||
class ResourceGenerator < ModelGenerator
|
class ResourceGenerator < ModelGenerator
|
||||||
hook_for :resource_controller
|
hook_for :resource_controller do |base, controller|
|
||||||
|
base.invoke controller, [ base.name.pluralize, base.options[:actions] ]
|
||||||
|
end
|
||||||
|
|
||||||
class_option :actions, :type => :array, :default => [], :banner => "ACTION ACTION",
|
class_option :actions, :type => :array, :default => [], :banner => "ACTION ACTION",
|
||||||
:desc => "Actions for the resource controller", :aliases => "-a"
|
:desc => "Actions for the resource controller", :aliases => "-a"
|
||||||
|
@ -11,25 +13,8 @@ module Rails
|
||||||
class_option :singleton, :type => :boolean, :default => false, :aliases => "-i",
|
class_option :singleton, :type => :boolean, :default => false, :aliases => "-i",
|
||||||
:desc => "Supply to create a singleton controller"
|
:desc => "Supply to create a singleton controller"
|
||||||
|
|
||||||
def invoke_for_resource_controller
|
|
||||||
return unless options[:resource_controller]
|
|
||||||
|
|
||||||
klass = Rails::Generators.find_by_namespace(options[:resource_controller], :rails, :controller)
|
|
||||||
|
|
||||||
if klass
|
|
||||||
args = []
|
|
||||||
args << pluralize?(class_name)
|
|
||||||
args << options[:actions]
|
|
||||||
|
|
||||||
say_status :invoke, options[:resource_controller], :blue
|
|
||||||
klass.new(args, options.dup, _overrides_config).invoke(:all)
|
|
||||||
else
|
|
||||||
say "Could not find and invoke '#{options[:resource_controller]}'."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_resource_route
|
def add_resource_route
|
||||||
route "map.resource#{"s" unless options[:singleton]} :#{pluralize?(file_name)}"
|
route "map.resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -111,7 +111,7 @@ class AppGeneratorTest < GeneratorsTestCase
|
||||||
|
|
||||||
def test_rails_is_frozen
|
def test_rails_is_frozen
|
||||||
generator(:freeze => true, :database => "sqlite3").expects(:run).with("rake rails:freeze:edge", false)
|
generator(:freeze => true, :database => "sqlite3").expects(:run).with("rake rails:freeze:edge", false)
|
||||||
silence(:stdout){ generator.invoke(:all) }
|
silence(:stdout){ generator.invoke }
|
||||||
assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
|
assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ class AppGeneratorTest < GeneratorsTestCase
|
||||||
template.instance_eval "def read; self; end" # Make the string respond to read
|
template.instance_eval "def read; self; end" # Make the string respond to read
|
||||||
|
|
||||||
generator(:template => path, :database => "sqlite3").expects(:open).with(path).returns(template)
|
generator(:template => path, :database => "sqlite3").expects(:open).with(path).returns(template)
|
||||||
assert_match /It works!/, silence(:stdout){ generator.invoke(:all) }
|
assert_match /It works!/, silence(:stdout){ generator.invoke }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_usage_read_from_file
|
def test_usage_read_from_file
|
||||||
|
|
|
@ -22,7 +22,8 @@ class PluginGeneratorTest < GeneratorsTestCase
|
||||||
|
|
||||||
def test_invokes_default_test_framework
|
def test_invokes_default_test_framework
|
||||||
run_generator
|
run_generator
|
||||||
assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb"
|
assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb", /class PluginFuTest < ActiveSupport::TestCase/
|
||||||
|
assert_file "vendor/plugins/plugin_fu/test/test_helper.rb"
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_logs_if_the_test_framework_cannot_be_found
|
def test_logs_if_the_test_framework_cannot_be_found
|
||||||
|
|
|
@ -81,12 +81,6 @@ class ResourceGeneratorTest < GeneratorsTestCase
|
||||||
def test_singleton_resource
|
def test_singleton_resource
|
||||||
run_generator ["account", "--singleton"]
|
run_generator ["account", "--singleton"]
|
||||||
|
|
||||||
assert_file "app/controllers/account_controller.rb", /class AccountController < ApplicationController/
|
|
||||||
assert_file "test/functional/account_controller_test.rb", /class AccountControllerTest < ActionController::TestCase/
|
|
||||||
|
|
||||||
assert_file "app/helpers/account_helper.rb", /module AccountHelper/
|
|
||||||
assert_file "test/unit/helpers/account_helper_test.rb", /class AccountHelperTest < ActionView::TestCase/
|
|
||||||
|
|
||||||
assert_file "config/routes.rb" do |route|
|
assert_file "config/routes.rb" do |route|
|
||||||
assert_match /map\.resource :account$/, route
|
assert_match /map\.resource :account$/, route
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue