2012-02-27 40 views
1

這是我第一次製作自定義導軌生成器,我希望能夠根據傳遞給生成器的參數在模板中創建一個動態類,但我無法弄清楚如何使其格式正確。Ruby - 根據文件名創建一個類?

class Achievements::__FILE__ < Achievement 
    end 

這是我要創建的生成類,下面是生成器。另外在旁註中,我是否在我的生成器中創建目錄'成就'?

module Achiever 
    module Generators 
    class AchievementGenerator < Rails::Generators::Base 
     source_root File.expand_path('../templates', __FILE__) 
     argument :award, :type => :string 

     def generate_achievement 
     copy_file "achievement.rb", "app/models/achievement/#{file_name}.rb" 
     end 

     private 

     def file_name 
     award.underscore 
     end 

    end 
    end 
end 

回答

0

我想出了這個問題。而不是copy_file方法,我應該使用模板方法。這允許我在模板視圖內使用erb標籤,並且可以在視圖內調用file_name.classify,並且它將動態創建模型。

argument :award, :type => :string 

上面設置了什麼,因爲參數將在生成的模型中定義下面的類。

class Achievements::<%= file_name.classify %> < Achievement 
end 
2

使用Module#const_set。它會自動納入對象,所以你可以做這樣的事情:

foo.rb

# Defining the class dynamically. Note that it doesn't currently have a name 
klass = Class.new do 
    attr_accessor(:args) 
    def initialize(*args) 
    @stuff = args 
    end 
end 
# Getting the class name 
class_name = ARGV[0].capitalize 
# Assign it to a constant... dynamically. Ruby will give it a name here. 
Object.const_set(class_name, klass) 
# Create a new instance of it, print the class's name, and print the arguments passed to it. Note: we could just use klass.new, but this is more fun. 
my_klass = const_get(class_name).new(ARGV[1..-1]) 
puts "Created new instance of `" << my_klass.class << "' with arguments: " << my_klass.args.join(", ") 

我還沒有試過這種代碼出來呢,但它應該產生這樣的:

$ ruby foo.rb RubyRules pancakes are better than waffles 
Created new instance of `RubyRules' with arguments: pancakes, are, better, than, waffles 

此外,第一個參數const_set絕對必須開始帶有大寫字母數字字符(就像定義靜態常數),或Ruby WIL l會產生以下錯誤:

NameError: wrong constant name rubyRules 
     --- INSERT STACKTRACE HERE --- 
+0

謝謝Jwosty!這是一個非常好的答案在一個特定於ruby的應用程序。 – ericraio 2012-02-28 06:26:08

+0

當然,沒問題! – Jwosty 2012-02-28 14:04:04

相關問題