Skip to content

Instantly share code, notes, and snippets.

@josevalim
Created June 26, 2009 10:39
Show Gist options
  • Save josevalim/136408 to your computer and use it in GitHub Desktop.
Save josevalim/136408 to your computer and use it in GitHub Desktop.
# Rails Generators invocations types.
#
# = PROBLEM
#
# 1) Rails should provide hooks for other generators in other to
# provide agnosticism.
#
# 2) Plugins/gems should be able to hook into another generator even
# if a hook is not there.
# Provide a invoke_for method that will invoke a generators based
# on the option value.
#
class ControllerGenerator < Rails::Generators::NamedBase
invoke_for :test_framework, :template_engine
end
# When invoked like this:
#
# ruby script/generate controller Foo --test-framework=rspec
#
# It will do internally:
#
# invoke "rspec:generators:controller"
#
# So any test framework can be part of the "show" if it provides a
# "test_framework:generators:controller" piece.
#
# Rails comes with "test_unit:generators:controller" implemented.
# Allow one generator to hook into another. Let's suppose you want to have
# webrat to generate tests every time you invoke a controller. Since Rails
# does not provide such hooks, webrat will need to hook into controller
# and scaffold_controller to say: "hey, invoke me if the user wants to".
#
Rails::Generators::ControllerGenerator.invoke_if :webrat
# This will add two options to controller generator: "--webrat" and "--skip-webrat".
# So when invoked like this:
#
# ruby script/generate controller Foo --webrat
#
# The controller generator will search webrat and try to invoke it:
#
def invoke_webrat_if_supplied
return unless options[:webrat]
if find_by_namespace?("rails:generators:webrat") # search for webrat in the current namespace
invoke "rails:generators:webrat"
elsif find_by_namespace?("webrat:generators:controller") # search for specific behavior inside webrat
invoke "webrat:generators:controller"
else
invoke "webrat"
end
end
# But do I have to supply --webrat everytime?
# No, Rails will allow to set default generators options:
#
config.generators.webrat = true
# This is mechanism is used even with rails. Let's suppose you don't like
# helpers to be generated when you invoke a controller. Just do this:
#
config.generators.helper = false
# This is the default value, but you can still overwrite them when invoking:
#
# ruby script/generate controller Foo --helper
# How do I overwrite a default behavior?
#
# Rails come with fixtures but a lot of people uses fixture replacements.
# How a fixture replacement can say: "hey, do not use fixtures anymore.
# Use me, unless otherwise specified"?
#
# The user could do this:
#
config.generators.fixtures = false
config.generators.factory_girl = true
# But maybe we should provide a interface for generators tweak with
# Rails default options without required the user to do so:
#
# So FactoryGirl could do:
#
Rails::Generators::ModelGenerator.default_class_option_value :fixtures, false
Rails::Generators::ModelGenerator.invoke_if :factory_girl
# On the other hand, allowing this API would also allow factory girl
# to do like below, automatically turning on FactoryGirl. This would make
# generators to plugin without user explicit input, maybe leading to wrong
# behavior:
#
Rails::Generators::ModelGenerator.default_class_option_value :factory_girl, true
# So, a interface for changing default options should be provided or not?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment