1

可以说我有这个模块:

module Template

 def self.included(base)

    base.class_eval do
      before_validation(:on => :create) { sanitize_text! }
    end

    base.extend(ClassMethods)
 end

 module ClassMethods

   def sanitize_text!
     # some stuff
   end

 end

end

然后我有一个这样定义的模型:

class Invitation < ActiveRecord::Base
  include Template
end

请注意,我没有覆盖方法 sanitize_text!但是当我运行这个 Rails 时会给我一个错误:

未定义的方法“sanitize_text!” 为了 #

我不明白 - 是不是假设我的模型邀请已经从模块模板中包含了该方法?

4

3 回答 3

2

before_validation 将块称为实例,因此没有 sanitize_text!因为sanitize_text!是一个类方法。

定义 sanitize_text!在模块中,不作为类方法。

module Template
  ...
  def sanitize_text!
    # some stuff
  end
end
于 2012-05-15T11:13:15.263 回答
0

您已将其作为Class Method包含在内,而不是作为该模型的任何特定实例的方法。

要使用它,您需要将其称为:

Invitation.sanitize_text!

要在 Invitation 实例上调用它,请进行以下更改:

module Template

 def self.included(base)

    base.class_eval do
      before_validation(:on => :create) { sanitize_text! }
    end

    base.extend(ClassMethods)
 end

 def sanitize_text!
   # some stuff
 end

 module ClassMethods
 end

end

然后您就可以在特定方法上调用它:

@invitation.sanitize_text!
于 2012-05-15T11:18:25.057 回答
0

你这样做的方式是Invitation用 method 扩展类sanitize_text!,而不是Invitation.

如果您希望 instance 具有sanitize_text!,则最好将其重命名ClassMethodsInstanceMethods并更改self.included为具有此行:

base.send :include, InstanceMethods

所以整个代码看起来像这样:

module Template
  def self.included(base)
    base.class_eval do
      before_validation(:on => :create) { sanitize_text! }
    end

    base.send :include, InstanceMethods
  end

  module InstanceMethods
    def sanitize_text!
      # method body
    end
  end
end
于 2012-05-15T11:50:17.567 回答