你如何将自己传递给ruby中的class_eval?

klo*_*ner 2 ruby metaprogramming ruby-on-rails

我正在进行元编程任务,我正在尝试使用单个方法在调用类中定义多态关联,同时还定义目标类中的关联.我需要传入调用类的名称才能使关联正确.这是一个应该得到这个想法的片段:


class SomeClass < ActiveRecord::Base
    has_many :join_models, :dependent=>:destroy
end

class JoinModel < ActiveRecord::Base
  belongs_to :some_class
  belongs_to :entity, :polymorphic=>true
end

module Foo
 module ClassMethods
   def acts_as_entity
      has_many :join_models,  :as=>:entity, :dependent=>:destroy
      has_many :some_classes,  :through=>:join_models

      klass = self.name.tableize
      SomeClass.class_eval "has_many :#{klass}, :through=>:join_models"
   end
  end
end

Run Code Online (Sandbox Code Playgroud)

我想删除该klass=行,但不知道如何self将调用类的引用传递给class_eval.

有什么建议?

Mar*_*une 5

字符串参数将在当前上下文中解释,因此您可以在self.name那里调用,或name直接调用:

SomeClass.class_eval "has_many :#{name.tableize}, :through=>:join_models"
Run Code Online (Sandbox Code Playgroud)

如果不是对你正在使用块的字符串进行eval,请注意这class_exec是一个变体class_eval,允许您自然地传递参数.所以:

SomeClass.class_exec(name.tableize.to_sym) do |klass|
  has_many klass, :through=>:join_models
end
Run Code Online (Sandbox Code Playgroud)

这是1.8.7的新功能,所以你需要require 'backports/1.8.7'1.8.6.

注意:我假设您需要进行评估,因为在您的特定示例中,您可以直接调用该方法,不是吗?

SomeClass.has_many name.tableize.to_sym, :through=>:join_models
Run Code Online (Sandbox Code Playgroud)