Rails 3 Generators: Say Hello!
Ben Scofield, Former Viget
Still with me after the last batch of ported generators? Well, I’ve got something new for you this time – and by new, I mean unseen by Rails 2.3.5-looking eyes. That’s right, it’s time to take a look at the generators that make their first appearance in Rails 3!
[rails3] > rails generate model_subclass ... model_subclass is deprecated. Invoke model with --parent option instead.
Whoa! I’m not sure when the model_subclass generator was added to Rails, but I know it’s not present in 2.3.5. Is it just me, or does it seem a little … aggressive to deprecate something that hasn’t even been released in a stable version? Why not just get rid of it outright?
(Oh, and if you're wondering what it does, take a look at my quick explanation of the
--parent option in the model generator.)
[rails3] > rails generate stylesheets create public/stylesheets/scaffold.css
The stylesheets generator is the simplest generator that Rails 3 provides. You know the standard stylesheet you get from generating a scaffold? (I know, I know, I haven’t covered the scaffold generators yet. Rest assured, they’re similar enough to the Rails 2 scaffolds in this respect.) All this does is copy that stylesheet into your application for you. Heck, even the session_migration generator has to add the current timestamp to the migration file name.
[rails3] > rails generate generator Shoulda create lib/generators/shoulda create lib/generators/shoulda/shoulda_generator.rb create lib/generators/shoulda/USAGE create lib/generators/shoulda/templates
OK, the other new generators in Rails 3 are kind of lame, but the generator generator rocks. All the modularity I’ve pointed to in the new generator setup? This is where it pays off.
When you run this generator, you get two files and a directory. USAGE is for documentation, and will be shown as part of the help text when your generator is run. The Ruby file that’s created (in this case, shoulda.rb) looks like this:
class ShouldaFrameworkGenerator < Rails::Generators::NamedBase def self.source_root @source_root ||= File.expand_path('../templates', __FILE__) end end
Any generator that takes a named argument (like the model generator, as compared to the stylesheets one) inherits from Rails::Generators::NamedBase. The
source_root class method tells your new generator where to look for its templates (and sub-generators, if you want to create them).
The templates directory is, naturally enough, where you put the templates your generator needs. These are just Erb files (so you can use Ruby to inject dynamic content), though they may end in .rb, .yml, or whatever other file extension your generator may need to create.
There is a single unique option for the generator generator:
Options: [--namespace] # Namespace generator under lib/generators/name # Default: true
I don’t know that it’s ever a great practice to set this to false; any time you have multiple custom generators in your lib, you’ll need that namespacing to avoid potential conflicts in the USAGE file and the templates directory.
And that’s almost it for the tour! Coming up, we’ll take a look at the last two generators to cover: scaffold and scaffold_controller. After that, we’ll start to dig a little deeper. We’ll see how to take advantage of the modularity I’ve pointed out by swapping out frameworks (e.g., Shoulda for Test::Unit), and we’ll also explore details at the implementation level. See you next time!