Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Ensure scaffold works properly even if plural name is given. [#3062]

  • Loading branch information...
commit 0efedf2a30a12cdaa261556e3684c630690afe0f 1 parent 5096ba9
@josevalim josevalim authored
View
52 railties/lib/generators/base.rb
@@ -9,6 +9,8 @@ class Base < Thor::Group
include Thor::Actions
include Rails::Generators::Actions
+ add_runtime_options!
+
# Automatically sets the source root based on the class name.
#
def self.source_root
@@ -45,8 +47,10 @@ def self.namespace(name=nil)
#
# ==== Examples
#
- # class ControllerGenerator < Rails::Generators::Base
- # hook_for :test_framework, :aliases => "-t"
+ # module Rails::Generators
+ # class ControllerGenerator < Base
+ # hook_for :test_framework, :aliases => "-t"
+ # end
# end
#
# The example above will create a test framework option and will invoke
@@ -64,7 +68,49 @@ def self.namespace(name=nil)
# invoked. This allows any test framework to hook into Rails as long as it
# provides any of the hooks above.
#
- # Finally, if the user don't want to use any test framework, he can do:
+ # ==== Options
+ #
+ # This lookup can be customized with two options: :base and :as. The first
+ # is the root module value and in the example above defaults to "rails".
+ # The later defaults to the generator name, without the "Generator" ending.
+ #
+ # Let's suppose you are creating a generator that needs to invoke the
+ # controller generator from test unit. Your first attempt is:
+ #
+ # class AwesomeGenerator < Rails::Generators::Base
+ # hook_for :test_framework
+ # end
+ #
+ # The lookup in this case for test_unit as input is:
+ #
+ # "test_unit:generators:awesome", "test_unit"
+ #
+ # Which is not the desired the lookup. You can change it by providing the
+ # :as option:
+ #
+ # class AwesomeGenerator < Rails::Generators::Base
+ # hook_for :test_framework, :as => :controller
+ # end
+ #
+ # And now it will lookup at:
+ #
+ # "test_unit:generators:awesome", "test_unit"
+ #
+ # Similarly, if you want it to also lookup in the rails namespace, you just
+ # need to provide the :base value:
+ #
+ # class AwesomeGenerator < Rails::Generators::Base
+ # hook_for :test_framework, :base => :rails, :as => :controller
+ # end
+ #
+ # And the lookup is exactly the same as previously:
+ #
+ # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit"
+ #
+ # ==== Switches
+ #
+ # All hooks come with switches for user interface. If the user don't want
+ # to use any test framework, he can do:
#
# ruby script/generate controller Account --skip-test-framework
#
View
3  railties/lib/generators/erb/scaffold/scaffold_generator.rb
@@ -1,9 +1,10 @@
require 'generators/erb'
+require 'generators/resource_helpers'
module Erb
module Generators
class ScaffoldGenerator < Base
- include Rails::Generators::ScaffoldBase
+ include Rails::Generators::ResourceHelpers
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
View
62 railties/lib/generators/named_base.rb
@@ -97,67 +97,5 @@ def self.check_class_collision(options={})
end
end
end
-
- # Deal with controller names on scaffold. Also provide helpers to deal with
- # ActionORM.
- #
- module ScaffoldBase
- def self.included(base) #:nodoc:
- base.send :attr_reader, :controller_name, :controller_class_name, :controller_file_name,
- :controller_class_path, :controller_file_path
- end
-
- # Set controller variables on initialization.
- #
- def initialize(*args) #:nodoc:
- super
- @controller_name = name.pluralize
-
- base_name, @controller_class_path, @controller_file_path, class_nesting, class_nesting_depth = extract_modules(@controller_name)
- class_name_without_nesting, @controller_file_name, controller_plural_name = inflect_names(base_name)
-
- @controller_class_name = if class_nesting.empty?
- class_name_without_nesting
- else
- "#{class_nesting}::#{class_name_without_nesting}"
- end
- end
-
- protected
-
- # Loads the ORM::Generators::ActiveModel class. This class is responsable
- # to tell scaffold entities how to generate an specific method for the
- # ORM. Check Rails::Generators::ActiveModel for more information.
- #
- def orm_class
- @orm_class ||= begin
- # Raise an error if the class_option :orm was not defined.
- unless self.class.class_options[:orm]
- raise "You need to have :orm as class option to invoke orm_class and orm_instance"
- end
-
- action_orm = "#{options[:orm].to_s.classify}::Generators::ActiveModel"
-
- # If the orm was not loaded, try to load it at "generators/orm",
- # for example "generators/active_record" or "generators/sequel".
- begin
- klass = action_orm.constantize
- rescue NameError
- require "generators/#{options[:orm]}"
- end
-
- # Try once again after loading the file with success.
- klass ||= action_orm.constantize
- rescue Exception => e
- raise Error, "Could not load #{action_orm}, skipping controller. Error: #{e.message}."
- end
- end
-
- # Initialize ORM::Generators::ActiveModel to access instance methods.
- #
- def orm_instance(name=file_name)
- @orm_instance ||= @orm_class.new(name)
- end
- end
end
end
View
16 railties/lib/generators/rails/resource/resource_generator.rb
@@ -1,25 +1,19 @@
require 'generators/rails/model/model_generator'
+require 'generators/resource_helpers'
module Rails
module Generators
class ResourceGenerator < ModelGenerator #metagenerator
+ include ResourceHelpers
+
hook_for :resource_controller, :required => true do |base, controller|
- base.invoke controller, [ base.name.pluralize, base.options[:actions] ]
+ base.invoke controller, [ base.controller_name, base.options[:actions] ]
end
class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [],
:desc => "Actions for the resource controller"
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
- class_option :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName"
-
- def initialize(*args)
- super
- if name == name.pluralize && !options[:force_plural]
- say "Plural version of the model detected, using singularized version. Override with --force-plural."
- name.replace name.singularize
- end
- end
+ class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
def add_resource_route
route "map.resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
View
3  railties/lib/generators/rails/scaffold/scaffold_generator.rb
@@ -3,7 +3,8 @@
module Rails
module Generators
class ScaffoldGenerator < ResourceGenerator #metagenerator
- remove_hook_for :actions, :resource_controller
+ remove_hook_for :resource_controller
+ remove_class_option :actions
hook_for :scaffold_controller, :required => true
hook_for :stylesheets
View
5 railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -1,8 +1,9 @@
+require 'generators/resource_helpers'
+
module Rails
module Generators
class ScaffoldControllerGenerator < NamedBase
- # Add controller methods and ActionORM settings.
- include ScaffoldBase
+ include ResourceHelpers
check_class_collision :suffix => "Controller"
View
74 railties/lib/generators/resource_helpers.rb
@@ -0,0 +1,74 @@
+module Rails
+ module Generators
+ # Deal with controller names on scaffold and add some helpers to deal with
+ # ActiveModel.
+ #
+ module ResourceHelpers
+ def self.included(base) #:nodoc:
+ base.send :attr_reader, :controller_name, :controller_class_name, :controller_file_name,
+ :controller_class_path, :controller_file_path
+
+ base.send :class_option, :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName"
+ end
+
+ # Set controller variables on initialization.
+ #
+ def initialize(*args) #:nodoc:
+ super
+
+ if name == name.pluralize && !options[:force_plural]
+ say "Plural version of the model detected, using singularized version. Override with --force-plural."
+ name.replace name.singularize
+ assign_names!(self.name)
+ end
+
+ @controller_name = name.pluralize
+
+ base_name, @controller_class_path, @controller_file_path, class_nesting, class_nesting_depth = extract_modules(@controller_name)
+ class_name_without_nesting, @controller_file_name, controller_plural_name = inflect_names(base_name)
+
+ @controller_class_name = if class_nesting.empty?
+ class_name_without_nesting
+ else
+ "#{class_nesting}::#{class_name_without_nesting}"
+ end
+ end
+
+ protected
+
+ # Loads the ORM::Generators::ActiveModel class. This class is responsable
+ # to tell scaffold entities how to generate an specific method for the
+ # ORM. Check Rails::Generators::ActiveModel for more information.
+ #
+ def orm_class
+ @orm_class ||= begin
+ # Raise an error if the class_option :orm was not defined.
+ unless self.class.class_options[:orm]
+ raise "You need to have :orm as class option to invoke orm_class and orm_instance"
+ end
+
+ active_model = "#{options[:orm].to_s.classify}::Generators::ActiveModel"
+
+ # If the orm was not loaded, try to load it at "generators/orm",
+ # for example "generators/active_record" or "generators/sequel".
+ begin
+ klass = active_model.constantize
+ rescue NameError
+ require "generators/#{options[:orm]}"
+ end
+
+ # Try once again after loading the file with success.
+ klass ||= active_model.constantize
+ rescue Exception => e
+ raise Error, "Could not load #{active_model}, skipping controller. Error: #{e.message}."
+ end
+ end
+
+ # Initialize ORM::Generators::ActiveModel to access instance methods.
+ #
+ def orm_instance(name=file_name)
+ @orm_instance ||= @orm_class.new(name)
+ end
+ end
+ end
+end
View
3  railties/lib/generators/test_unit/scaffold/scaffold_generator.rb
@@ -1,9 +1,10 @@
require 'generators/test_unit'
+require 'generators/resource_helpers'
module TestUnit
module Generators
class ScaffoldGenerator < Base
- include Rails::Generators::ScaffoldBase
+ include Rails::Generators::ResourceHelpers
class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
check_class_collision :suffix => "ControllerTest"
Please sign in to comment.
Something went wrong with that request. Please try again.