代码之家  ›  专栏  ›  技术社区  ›  salt.racer

我可以在rails模型中定义_方法吗?

  •  21
  • salt.racer  · 技术社区  · 16 年前

    我的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 回复  |  直到 16 年前
        1
  •  80
  •   Community CDub    4 年前

    rails模型没有什么神奇之处,它只是一个普通的类,包含一堆预先存在的方法,

    所以,问题是“我能在类中定义_方法吗”?

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

    重要的区别在于您无法定义方法 在课堂上 在某种情况下 方法

    例如:

    class Cow
      define_method "speak" do
        "MOOOO"
      end
    end
    
    Cow.new.speak
    => "MOOOO"
    

    这应该行得通。请注意,您正在类Cow上定义它,因此您已经拥有的任何其他Cow都将自动添加该方法。

    第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 是私有的,私有方法只能访问它们所在的对象。在这种情况下,, 定义方法

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

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

    class Cow
      def add_speak_just_me
        class << self
          define_method "speak" do
            "MOOOO added for just me"
          end
        end
      end
    end
    
    Cow.new.speak
    NoMethodError: undefined method 'speak' for #<Cow:0xb7c72b78>
    
    c = Cow.new
    c.add_speak_just_me
    c.speak
    => "MOOOO added for just me" # it works, hooray
    
    Cow.new.speak # this new cow doesn't have the method, it hasn't been automatically added
    NoMethodError: undefined method `speak' for #<Cow:0xb7c65b1c>
    

    这是怎么回事?到兔子洞里去!

    请阅读以下内容: http://dannytatom.me/metaid/ 祝你好运。当您意识到向实例中“添加方法”实际上并不是将其添加到实例中时,它会有所帮助:-)

        2
  •  6
  •   Kabir Sarin    10 年前

    define_method 不起作用(因为它定义了实例方法),下面是您的答案:

    define_singleton_method :)

        3
  •  2
  •   Tim Harding    16 年前

    我的实例方法foo正在打开类并在其上定义bar,这样我就可以在我的实例上调用它。更有经验的人会让我们知道这是不是同时打开了一罐蠕虫。

    不过,了解您的具体用途会很有用。

    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"
    
        4
  •  1
  •   Avdi    16 年前