2. About Me
✤ Josh Moore (
✤ www.codingforrent.com
✤ twitter.com/codingforrent
✤ http://github.com/joshsmoore
✤ Ruby
✤ Watir at work
✤ Rails on the Google App Engine for hobby
✤ maintain rails_dm_datastore gem
7. The Problem
✤ You cannot deviate from the rails convection without losing
productivity.
✤ Who uses something besides the normal rails libraries?
✤ ERB, ActiveRecord, Test::Unit, fixtures
✤ The generators are not nearly as nice as they used to be.
8. Are you sure this is a big deal?
✤ I use DataMapper, Haml
✤ Generator for views does not work
✤ Generator for models does not work
✤ Scaffold does not work
9. Fixing it
✤ Pretty much impossible in Rails 2
✤ You could make your own generator, but not integrated different
names or syntax
10. Rails 3 goal
✤ Modularity - Easy to switch components
✤ But, the generators still produce the same objects by default
✤ ActiveRecord
✤ TestUnit
✤ ERB
11. How does Rails 3 help?
✤ Meta Generators
✤ Scaffold is now a meta generator
✤ Hooks
✤ Internals are complete new - rebuilt with Thor
15. Hooks
✤ Allow one generator to invoke another generator
✤ Can control what generator is invoked
✤ Allow you to override the defaults
✤ Create custom hooks if you want to
16. Override the defaults
✤ For each command
✤ --template-engine=haml
✤ --orm=datamapper
✤ Change the default in config/application.rb
config.generators do |g|
g.orm :datamapper
g.template_engine :haml
g.test_framework :test_unit, :fixture_replacement
=> :factory_girl
end
17. Thor
✤ “Map options to a class. Simply create a class with the appropriate
annotations and have options automatically map to functions and
parameters.”
✤
✤ Plan English: Replacement for Rake and sake with a sane way to pass
parameters, which means it makes it easy to map command line
arguments to parameters and methods in a Ruby class
18. > thor app:install myname --force
> thor app -L
class App < Thor
map "-L" => :list
desc "install APP_NAME", "install one of the available apps"
method_options :force => :boolean, :alias => :string
def install(name)
user_alias = options[:alias]
if options.force?
puts "forcing deletion"
end
puts 'installing'
end
desc "list [SEARCH]", "list all of the available apps, limited by SEARCH"
def list(search="")
# list everything
if search == ""
puts "searching everything"
else
puts "searching for #{search}"
end
end
end
19. Things that are hard in Rake
✤ --force - boolean parameters are harder
✤ mapping -L to the app:list action
✤ parameters mapped to Ruby types (boolean, string, number, array,
and hash)
20. What does this mean for Rails
generators?
✤ Thor::Actions
✤ General purpose actions
✤ Rails::Generators::Actions
✤ actions specific to rails
✤ Application templates and Rails generators now share same API
(Thor::Actions)
22. There’s a generator for that
✤ rails g generator NAME
✤ creates these files
✤ haml/
✤ haml_generator.rb - Gets called when you execute the generator
✤ USAGE - Describes the generator
✤ templates/ - templates go here
23. haml_generator.rb Explained
Code
✤ Place your code in instance methods
✤ It has access to all arguments and options
✤ All public instance methods will be executed (probably in the order
that the methods are defined in)
✤ Inherits from Thor::Group
24. haml_generator.rb Explained
Parameters
✤ Arguments and options
✤ Arguments are non-named parameters that come first
✤ Options are named parameters that come last
✤ Straight from Thor
25. Arguments
✤ Described at the top of your class
✤ The order they are declared is the order they will be accepted on the
command line
26. Arguments Example
class HamlGenerator < Rails::Generators::NamedBase
argument :test_arg, :type => :numeric, :banner => '<number of units>'
argument :test_arg3, :type => :string, :required => false, :default => 'default'
27. Declaring Arguments
✤ :desc - Description for the argument.
✤ :required, :optional - If the argument is required or not.
✤ :type - The type of the argument, can be
✤ :string, :hash, :array, :numeric.
✤ :default - Default value for this argument. It cannot be required and
have default values.
✤ :banner - String that shows the input format
28. Argument Rules
✤ Once an argument is declared optional all remaining arguments must
be optional
✤ you cannot “miss” an optional argument
✤ Once an array argument is declared it will parse everything option
after it into the array
✤ Access the value of the argument by calling its name (attr_accessor)
✤ Required by default
29. Options
✤ Also described at the top of your class
✤ But, the order does not matter
30. Option Example
class HamlGenerator < Rails::Generators::NamedBase
class_option :test_arg, :type => :numeric, :banner => '<number of units>'
class_option :test_arg3, :type => :string, :required => false, :default => 'default'
31. Declaring a class_option
✤ :desc - Description for the argument.
✤ :required, :optional - If the argument is required or not.
✤ :type - The type of the argument, can be
✤ :boolean, :numeric, :hash, :array, :string
✤ :default - Default value for this argument. It cannot be required and
have default values.
✤ :banner - String that shows the input format
32. class_option rules
✤ use the --name-of-class-option to set the class option
✤ optional by default
✤ underscores (_) in option name become dashes (-)
33. Implementing Hooks
✤ simply call hook_for :<NAME>
✤ switches provided --[no|skip]-test-framework
✤ under the hood
✤ creates a class_option
✤ invokes “invoke_from_option”