2012-02-27 14 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私は次の行に沿って何かエラーを生成します:

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

ありがとうJwosty!これは、Ruby固有のアプリケーションの非常に良い答えです。 – ericraio

+0

もちろん、問題ありません! – Jwosty

関連する問題