The calendar is gone.
Click here to view posts


Rails generate generators
Creating a generator for rails is simple enough.[1] You have to create a directory in lib or vendor and call it generators. Then you create ruby class (Name)Generator that extends Rails::Generator::NamedBase or Rails::Generator. You create a method called manifest that will do the actions to for your generator.

In the manifest you call record with a block. Somethings you can do in the block?
#if options[:svn] is set this will run the svn add command
#I was creating controllers. this call checks name spaces of rails objects (Not user created objects)
#m.class_collisions class_path, "#{controller_name.camelize}Controller", "#{controller_name.camelize}ControllerTest", "#{controller_name.camelize}Helper"
#This just copies files from point a to point b.
#The file_options hash accepts :chmod and :shebang and :collision options.
#m.file "lib/rest_resource.rb", "lib/rest_resource.rb",{}
#m.directory File.join('lib','generators', class_name)
#this allows you to use ERB to create cool stuff
#m.template 'USAGE', File.join('lib', 'generators',class_name,"USAGE")
# Display a README.
#m.readme "INSTALL"

#I have yet to use these
#m.migration_template(relative_source, relative_destination, template_options = {:migration_file_name=>"not sure"})
#alters route.rb file
#m.route_resources(*resources)
#m.complex_template(relative_source, relative_destination, template_options = {[:assigns]['template_for_inclusion'] })
#check if its already there
#m.identical?(source, destination, &block)
</pre>
<br><br>
Simple enough so lets script it! Thats right I created a generator to create generators. <br>
<pre>
sbecker@funtime-theme-park:~/rails/gens$ ruby script/generate generator test
      create  lib/generators/test
      create  lib/generators/test/templates
      create  lib/generators/test/templates/controllers
      create  lib/generators/test/templates/tests
      create  lib/generators/test/templates/views
      create  lib/generators/test/templates/models
      create  lib/generators/test/templates/helpers
      create  lib/generators/test/templates/libs
      create  lib/generators/test/USAGE
      create  lib/generators/test1/test_generator.rb


The script creates the correct file structure,the generator.rb file and the templates folder with some default folders. If you do not need all these folders then delete them. I think it helps keep to the templates grouped together.

To create the generator I have two templates and the manifest. The templates are for the USAGE file which is from the controller USAGE, and a basic manifest which has example calls that i listed above. The manifest for the generator is simple.
class GeneratorGenerator < Rails::Generator::NamedBase
	attr_accessor :gen_path,:gen_name
	def initialize(*runtime_args)
		super(*runtime_args)
		raise "You need a Generator name" if runtime_args.first.size<1
                #class_name is auto formated and not reallly what i want
		@gen_name=runtime_args.first.first
                #simple check needs to be better
		raise " You already have a generator called #{gen_name}" if File.directory?(RAILS_ROOT+"/lib/generators/#{gen_name.downcase}")
		#the rest of the other actions, currently not used
                @actions = @args.empty? ? [] : Array(@args)
		@gen_path=@gen_name.downcase
	end
	def manifest
		record do |m|

			#Think of a way to check current gens
			m.directory File.join('lib','generators', gen_path)
			m.directory File.join('lib','generators', gen_path,'templates')
			m.directory File.join('lib','generators', gen_path,'templates','controllers')
			m.directory File.join('lib','generators', gen_path,'templates','tests')
			m.directory File.join('lib','generators', gen_path,'templates','views')
			m.directory File.join('lib','generators', gen_path,'templates','models')
			m.directory File.join('lib','generators', gen_path,'templates','helpers')
			m.directory File.join('lib','generators', gen_path,'templates','libs')
			m.template 'USAGE', File.join('lib', 'generators',gen_path,"USAGE")
			m.template 'generator.rb', File.join('lib', 'generators',gen_path,"#{gen_name}_generator.rb")
		end
	end
end


I will add the generator code to my svn soon.

Useful sites:
[1] http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators
[2] http://www.aidanf.net/rails/creating-your-own-generators-in-rails

Login generator
I have posted about my ruby on rails generator that generates generators before. When I created this I did not know the generator code that well. Sadly this is still the case. I used generators for my one task saving me from created a nearly similar files over and over again. But Becker could you have not metaprogramed it? No each model had a common idea and interface but in the end the code was very different. I could have reduced the code and created a mixin for most of the methods, but it's a little late for that. Also I do not think I want to create a mixin for code that should be changing a lot.
Long story shorter I created some generators. I found my self creating another rails app for my websites and I am writing the login code over and over again. I thought why not generate? Then I thought why has someone not done this? But they have and, each of the generators work. They all have good attributes and bad ones but, none of them are 100% what I wanted. So I am going to make my own login generator. I will post it in my svn when its ok. I also realize the literature on generators is lacking. I also feel that the amount of generators that have been created is very low. It might be the most under used feature in RoR.