Converting rails 2 generators to rails 3?
How difficult is it to convert rails 2 generators to rails 3? I keep finding useful plugins but then finding that the generators are only for rails 2. I realize some of it is just a convenience, but if migrating the generator to rails 3 is as simple as tweaking a few lines in the generator code, I would be down to just do that (and commit the work to github for future users as well).
Here's one such generator I've been thinking about using, for example (from feedback)
require File.expand_path(File.dirname(__FILE__) + "/lib/insert_routes.rb")
class FeedbackFormGener开发者_开发问答ator < Rails::Generator::Base
attr_accessor :name,
:model_class_name,
:controller_class_name,
:helper_class_name,
:mailer_class_name
def initialize(runtime_args, runtime_options = {})
super
@name = (runtime_args[0] || "feedback").downcase
@model_class_name = name.classify
@mailer_class_name = "#{@model_class_name}Mailer"
@controller_class_name = "#{@model_class_name.pluralize}Controller"
@helper_class_name = "#{@model_class_name.pluralize}Helper"
#@js_framework = (runtime_options[''])
end
def manifest
record do |m|
puts "hello"
add_model(m)
add_mailer(m)
add_controller(m)
add_helper(m)
add_views(m)
add_routes(m)
add_unit_test(m)
add_functional_test(m)
add_stylesheet(m)
add_javascript(m)
add_images(m)
end
end
def add_stylesheet(m)
m.directory 'public/stylesheets'
m.file 'feedback.css', 'public/stylesheets/feedback.css'
end
def add_javascript(m)
m.directory 'public/javascripts'
file_name = options[:jquery] ? 'jquery.feedback.js' : 'prototype.feedback.js'
m.file file_name, "public/javascripts/#{file_name}"
end
def add_images(m)
m.directory 'public/images/feedback'
m.file "images/feedback_tab.png", "public/images/feedback/feedback_tab.png"
m.file "images/feedback_tab_h.png", "public/images/feedback/feedback_tab_h.png"
m.file "images/closelabel.gif", "public/images/feedback/closelabel.gif"
m.file "images/loading.gif", "public/images/feedback/loading.gif"
end
def add_model(m)
m.template 'feedback_model.rb.erb', "app/models/#{name}.rb"
end
def add_mailer(m)
m.template 'feedback_mailer.rb.erb', "app/models/#{name}_mailer.rb"
m.directory "app/views/#{name}_mailer"
m.file 'views/feedback_mailer/feedback.html.erb', "app/views/#{name}_mailer/feedback.html.erb"
end
def add_controller(m)
m.template 'feedbacks_controller.rb.erb', "app/controllers/#{name.pluralize}_controller.rb"
end
def add_helper(m)
template_name = options[:jquery] ? 'feedbacks_helper.rb.jquery.erb' : 'feedbacks_helper.rb.prototype.erb'
m.template template_name, "app/helpers/#{name.pluralize}_helper.rb"
end
def add_views(m)
m.directory "app/views/#{name.pluralize}"
m.file 'views/feedbacks/new.html.erb', "app/views/#{name.pluralize}/new.html.erb"
end
def add_routes(m)
m.route_name "new_feedback", "feedbacks/new", {:controller => name.pluralize, :action => "new"}
m.route_name "feedback", "feedbacks", {:controller => name.pluralize, :action => "create"}
end
def add_unit_test(m)
m.template 'feedback_test.rb.erb', "test/unit/#{name}_test.rb"
m.template 'feedback_mailer_test.rb.erb', "test/unit/#{name}_mailer_test.rb"
end
def add_functional_test(m)
m.template 'feedbacks_controller_test.rb.erb', "test/functional/#{name.pluralize}_controller_test.rb"
end
protected
def add_options!(opt)
opt.separator ''
opt.separator 'Options:'
opt.on("--jquery",
"Use jquery Javascript framework, default is Prototyp") { |v| options[:jquery] = true }
end
end
It really depends on the sort of generator it is. A lot of the internals of Rails have changed a lot between 2 and 3. Let me show you my recent experience in converting a very simple migration generator which I have in one of my apps from 2 to 3.
Here's the 2 code:
class LegacyMigrationGenerator < MigrationGenerator
def manifest
record do |m|
m.migration_template 'legacy_migration.rb', 'db/migrate'
end
end
end
And here's the 3 code:
require 'rails/generators/active_record'
class LegacyMigrationGenerator < ActiveRecord::Generators::Base
source_root File.expand_path('../templates', __FILE__)
def create_migration_file
migration_template "legacy_migration.rb", "db/migrate/#{file_name}.rb"
end
end
So, as you can see - totally different method to override, had to inherit from a generator now, had to call this source_root
now (used to be automatic), and no longer calling the migration_template
in a block.
This small conversion took me about three hours to hunt down all the pieces through the source. The best part was that I didn't have to change my template at all (and I believe that will be true for most generators).
All that being said, I think migration generation is probably the least well documented, looking at the generator guide it really doesn't seem too challenging to recreate generators in Rails3. Definitely worth taking a crack at in my opinion.
Also, I know that one of the authors of that guide has a book coming out soon with a chapter all about generators - so it's definitely something which will be getting more attention.
精彩评论