我可以在rails模型中使用define_method吗?

时间:2008-11-19 17:58:45

标签: ruby-on-rails ruby

我的rails模型的代码试图在模型中define_method(method_name)

我一直在:

NoMethodError: undefined method `define_method'

我做错了什么?我是在错误的地方做这件事吗我需要附加到此模型的此方法。我还能在哪里定义这种方法?

编辑: 对于那些要求查看代码的人:

for field in rdev_fields
  next if self.attributes.include?(field)
  count = count + 1
  rdev_hash[field.to_sym] = self.attributes["attribute#{count}"]
  if !self.respond_to?(field) then
    define_method("#{field}") do
      self.send("attribute#{count}".to_sym)
    end
  end
end

4 个答案:

答案 0 :(得分:77)

没有什么神奇的或关于rails模型,它只是一个普通的类,有一堆预先存在的方法,

所以,问题是“我可以在课堂上定义方法吗?”

第1部分:是的,你可以。

重要的区别在于您可以在类中定义方法而不是方法中的

例如:

class Cow
  define_method "speak" do
    "MOOOO"
  end
end

Cow.new.speak
=> "MOOOO"

这应该可以正常工作。请注意,您在类Cow上定义它,因此您已经拥有的任何其他Cows将自动添加该方法。

第2部分:如果要在实例方法中定义方法,该怎么办?

您无法从实例方法定义方法,因此您必须获取类,并使用它来定义方法。像这样:

class Cow
  def add_speak
    self.class.send(:define_method, :speak) do
      "MOOOO added"
    end
  end
end

Cow.new.speak
NoMethodError: undefined method 'speak' for #<Cow:0xb7c48530>

Cow.new.add_speak
Cow.new.speak
=> "MOOOO added"

问题解决了。精明的读者会注意到,在这个例子中我使用的是send(:define_method) - 这是必需的,因为define_method是私有的,私有方法只能被他们所在的东西访问。在这种情况下,{{ 1}}在类中,我们在实例中,所以我们不能直接访问它。

如上所述,我们将该方法直接添加到类中,因此已经存在的所有其他Cows也将自动添加speak方法。

第3部分:如果您只想为一个对象定义一个方法,而不是该类的所有对象,您会怎么做?

示例:

define_method

这是如何工作的?你去了rabbithole!

阅读本文:http://dannytatom.me/metaid/祝你好运。当你意识到“向一个实例添加一个方法”实际上根本没有将它添加到实例时会有所帮助: - )

答案 1 :(得分:2)

能够拼凑这个。虽然很少了解实际发生的事情。

我的实例方法foo正在打开类并在其上定义条,以便我可以在我的实例上调用它。更有经验的人会告诉我们这是否同时打开了一堆蠕虫。

虽然知道你的具体用途会很有用。

class User < ActiveRecord::Base

  def foo
    (class << self; self; end).class_eval do
      define_method(:bar) {puts "bar"}
    end
  end
end

u = User.first
u.foo
u.bar #=> "bar"

答案 2 :(得分:2)

如果你来到这里寻找如何动态定义CLASS方法,因为define_method没有工作(因为它定义了INSTANCE方法),这是你的答案:

使用define_singleton_method:)

答案 3 :(得分:1)

你的问题的答案是“是的,你可以”。至于为什么它不适合你 - 如果你没有为代码提供一些上下文,那么就不可能确定原因。